Firmware & Diagnostics File Transfer - CSMS Developer Guide
Based on OCPP 1.6 Edition 2 FINAL, Section 8 (normative). This guide covers the file transfer mechanisms used for firmware updates and diagnostics uploads from the CSMS (Central System) perspective.
1. Overview
IntroductionThis section covers the file transfer mechanisms used for firmware updates and diagnostics uploads. These operations belong to the Firmware Management feature profile and involve four OCPP messages working together.
The Firmware Management profile is defined as: "Support for firmware update management and
diagnostic log file download." Implementation of this profile is optional (only the Core profile is required). The exact profile identifier string used in the SupportedFeatureProfiles configuration key is FirmwareManagement.
Messages
| Message | Direction | Purpose |
|---|---|---|
UpdateFirmware | Central System -> Charge Point | Instruct CP to download and install new firmware |
FirmwareStatusNotification | Charge Point -> Central System | Report firmware download/install progress |
GetDiagnostics | Central System -> Charge Point | Request CP to upload diagnostics logs |
DiagnosticsStatusNotification | Charge Point -> Central System | Report diagnostics upload progress |
Supported Transfer Protocols
Controlled by the configuration key SupportedFileTransferProtocols (CSL -- Comma Separated List).
Supported Protocols
FTP, FTPS, HTTP, HTTPS
FTP URL Format
ftp://user:password@host:port/path
user:password@, :password, and :port may be excluded
Recommendations:
- Use FTP or FTPS over HTTP because FTP(S) is better optimized for large binary data and supports resume capability for interrupted downloads and uploads
- To ensure that the correct firmware is downloaded, it is recommended that the firmware is also digitally signed
2. Download Firmware (UpdateFirmware)
Section 8.1When a Charge Point is notified about new firmware, it needs to be able to download this firmware. The Central System supplies in the request a URL where the firmware can be downloaded. The URL also contains the protocol which must be used to download the firmware.
Flow
Central System Charge Point
| |
|-- UpdateFirmware.req(location, --> |
| retrieveDate, [retries], |
| [retryInterval]) |
| |
| <-- UpdateFirmware.conf() -----|
| |
| [Waiting for retrieveDate...] |
| |
| <-- FirmwareStatusNotification.req -----| status: Downloading
| (status: Downloading) |
|-- FirmwareStatusNotification.conf() --> |
| |
| [Downloading...] |
| |
| <-- FirmwareStatusNotification.req -----| status: Downloaded
| (status: Downloaded) |
|-- FirmwareStatusNotification.conf() --> |
| |
| [Waiting for transactions to finish] |
| |
| <-- FirmwareStatusNotification.req -----| status: Installing
| (status: Installing) |
|-- FirmwareStatusNotification.conf() --> |
| |
| [Installing...] |
| |
| === alt: automatic reboot === |
| [Reboot] |
| <-- BootNotification.req -----|
|-- BootNotification.conf() --> |
| <-- FirmwareStatusNotification.req -----| status: Installed
|-- FirmwareStatusNotification.conf() --> |
| |
| === alt: manual reboot === |
| <-- FirmwareStatusNotification.req -----| status: Installed
|-- FirmwareStatusNotification.conf() --> |
|-- Reset.req(Hard) --> |
| <-- Reset.conf() -----|
| [Reboot] |
| <-- BootNotification.req -----|
|-- BootNotification.conf() --> |Behavior
- Central System can notify a Charge Point that it needs to update its firmware. The
Central System SHALL send an
UpdateFirmware.reqPDU to instruct the Charge Point to install new firmware. The PDU SHALL contain a date and time after which the Charge Point is allowed to retrieve the new firmware and the location from which the firmware can be downloaded. - Upon receipt of an
UpdateFirmware.reqPDU, the Charge Point SHALL respond with anUpdateFirmware.confPDU (empty response -- acknowledgement only). - The Charge Point SHOULD start retrieving the firmware as soon as possible after retrieveDate.
- During downloading and installation of the firmware, the Charge Point MUST send
FirmwareStatusNotification.reqPDUs to keep the Central System updated with the status of the update process. - The Charge Point SHALL, if the new firmware image is "valid", install the new firmware as soon as it is able to.
- If it is not possible to continue charging during installation of firmware, it is recommended to wait until the Charging Session has ended (Charge Point
idle) before commencing installation, and set connectors that are not in use to
UNAVAILABLEwhile the Charge Point waits for the Session to end. - After installation, the Charge Point may reboot automatically or wait for a manual
Reset.req(Hard)from the Central System.
Best practice: It is good practice to first reboot the Charge Point to check the new firmware is booting and able to connect to the Central System, before sending the status: Installed. This is not a requirement.
UpdateFirmware.req (Central System -> Charge Point)
| Field | Type | Required | Description |
|---|---|---|---|
location | anyURI (string) | Yes | URI pointing to a location from which to retrieve the firmware. |
retrieveDate | dateTime (ISO 8601) | Yes | Date and time after which the Charge Point is allowed to retrieve the (new) firmware. |
retries | integer | No | How many times Charge Point must try to download the firmware before giving up. If not present, the Charge Point decides. |
retryInterval | integer | No | The interval in seconds after which a retry may be attempted. If not present, the Charge Point decides. |
{
"type": "object",
"properties": {
"location": {
"type": "string",
"format": "uri"
},
"retries": {
"type": "integer"
},
"retrieveDate": {
"type": "string",
"format": "date-time"
},
"retryInterval": {
"type": "integer"
}
},
"additionalProperties": false,
"required": ["location", "retrieveDate"]
}[2, "msg-001", "UpdateFirmware", {
"location": "ftp://firmware.example.com/cp/v2.1.0/firmware.bin",
"retrieveDate": "2024-03-15T02:00:00Z",
"retries": 3,
"retryInterval": 300
}]UpdateFirmware.conf (Charge Point -> Central System)
Empty response. No fields are defined.
{
"type": "object",
"properties": {},
"additionalProperties": false
}[3, "msg-001", {}]3. Upload Diagnostics (GetDiagnostics)
Section 8.2When a Charge Point is requested to upload a diagnostics file, the Central System supplies in the request a URL where the Charge Point should upload the file. The URL also contains the protocol which must be used to upload the file.
Flow
Central System Charge Point
| |
|-- GetDiagnostics.req(location, --> |
| [retries], [retryInterval], |
| [startTime], [stopTime]) |
| |
| <-- GetDiagnostics.conf([fileName]) -----|
| |
| [Uploading diagnostics file...] |
| |
| <-- DiagnosticsStatusNotification.req-----| status: Uploading
| (status: Uploading) |
|-- DiagnosticsStatusNotification.conf()--> |
| |
| [Uploaded diagnostics file...] |
| |
| <-- DiagnosticsStatusNotification.req-----| status: Uploaded
| (status: Uploaded) |
|-- DiagnosticsStatusNotification.conf()--> |Behavior
- Central System can request a Charge Point for diagnostic information. The Central
System SHALL send a
GetDiagnostics.reqPDU for getting diagnostic information of a Charge Point with a location where the Charge Point MUST upload its diagnostic data to and optionally a begin and end time for the requested diagnostic information. - Upon receipt of a
GetDiagnostics.reqPDU, and if diagnostics information is available, then the Charge Point SHALL respond with aGetDiagnostics.confPDU stating the name of the file containing the diagnostic information that will be uploaded. The Charge Point SHALL upload a single file. Format of the diagnostics file is not prescribed. If no diagnostics file is available, thenGetDiagnostics.confSHALL NOT contain a file name. - During uploading of a diagnostics file, the Charge Point MUST send
DiagnosticsStatusNotification.reqPDUs to keep the Central System updated with the status of the upload process.
GetDiagnostics.req (Central System -> Charge Point)
| Field | Type | Required | Description |
|---|---|---|---|
location | anyURI (string) | Yes | The location (directory) where the diagnostics file shall be uploaded to. |
retries | integer | No | How many times Charge Point must try to upload the diagnostics before giving up. If not present, the Charge Point decides. |
retryInterval | integer | No | The interval in seconds after which a retry may be attempted. If not present, the Charge Point decides. |
startTime | dateTime (ISO 8601) | No | Date and time of the oldest logging information to include in the diagnostics. |
stopTime | dateTime (ISO 8601) | No | Date and time of the latest logging information to include in the diagnostics. |
{
"type": "object",
"properties": {
"location": {
"type": "string",
"format": "uri"
},
"retries": {
"type": "integer"
},
"retryInterval": {
"type": "integer"
},
"startTime": {
"type": "string",
"format": "date-time"
},
"stopTime": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false,
"required": ["location"]
}[2, "msg-002", "GetDiagnostics", {
"location": "ftp://logs.example.com/diagnostics/",
"retries": 2,
"retryInterval": 60,
"startTime": "2024-03-01T00:00:00Z",
"stopTime": "2024-03-14T23:59:59Z"
}]GetDiagnostics.conf (Charge Point -> Central System)
| Field | Type | Required | Description |
|---|---|---|---|
fileName | CiString255Type (max 255) | No | Name of the file with diagnostic information that will be uploaded. Not present when no diagnostic information is available. |
{
"type": "object",
"properties": {
"fileName": {
"type": "string",
"maxLength": 255
}
},
"additionalProperties": false
}[3, "msg-002", {
"fileName": "diagnostics-CP001-20240314-143022.zip"
}]4. Status Notification Messages
ProtocolFirmwareStatusNotification.req (Charge Point -> Central System)
A Charge Point sends notifications to inform the Central System about the progress of the
firmware update. The Charge Point SHALL send a FirmwareStatusNotification.req PDU for informing the Central System about the progress of the downloading and installation
of a firmware update.
The Charge Point SHALL only send the status Idle after receipt of a TriggerMessage for a Firmware Status Notification, when it is not busy
downloading/installing firmware.
| Field | Type | Required | Description |
|---|---|---|---|
status | FirmwareStatus (enum) | Yes | The progress status of the firmware installation. |
FirmwareStatus Enum Values
| Value | Description |
|---|---|
Downloaded | New firmware has been downloaded by Charge Point. |
DownloadFailed | Charge Point failed to download firmware. |
Downloading | Firmware is being downloaded. |
Idle | Charge Point is not performing firmware update related tasks. Status Idle SHALL only be used in a FirmwareStatusNotification.req that was triggered by a TriggerMessage.req. |
InstallationFailed | Installation of new firmware has failed. |
Installing | Firmware is being installed. |
Installed | New firmware has successfully been installed in charge point. |
Happy Path
Downloading ->Downloaded ->Installing ->Installed Error Paths
Downloading -> DownloadFailedDownloading -> Downloaded -> Installing -> InstallationFailed{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"Downloaded",
"DownloadFailed",
"Downloading",
"Idle",
"InstallationFailed",
"Installing",
"Installed"
]
}
},
"additionalProperties": false,
"required": ["status"]
}[2, "msg-003", "FirmwareStatusNotification", {
"status": "Downloading"
}]FirmwareStatusNotification.conf (Central System -> Charge Point): Empty response. No fields are defined.
[3, "msg-003", {}]DiagnosticsStatusNotification.req (Charge Point -> Central System)
Charge Point sends a notification to inform the Central System about the status of a
diagnostics upload. The Charge Point SHALL send a DiagnosticsStatusNotification.req PDU to inform the Central System that the upload of diagnostics is busy or has finished successfully
or failed.
The Charge Point SHALL only send the status Idle after receipt of a TriggerMessage for a Diagnostics Status Notification, when it is not busy
uploading diagnostics.
| Field | Type | Required | Description |
|---|---|---|---|
status | DiagnosticsStatus (enum) | Yes | The status of the diagnostics upload. |
DiagnosticsStatus Enum Values
| Value | Description |
|---|---|
Idle | Charge Point is not performing diagnostics related tasks. Status Idle SHALL only be used in a DiagnosticsStatusNotification.req that was triggered by a TriggerMessage.req. |
Uploaded | Diagnostics information has been uploaded. |
UploadFailed | Uploading of diagnostics failed. |
Uploading | File is being uploaded. |
Happy Path
Uploading -> UploadedError Path
Uploading -> UploadFailed{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"Idle",
"Uploaded",
"UploadFailed",
"Uploading"
]
}
},
"additionalProperties": false,
"required": ["status"]
}[2, "msg-004", "DiagnosticsStatusNotification", {
"status": "Uploading"
}]DiagnosticsStatusNotification.conf (Central System -> Charge Point): Empty response. No fields are defined.
[3, "msg-004", {}]5. TriggerMessage Integration
Remote TriggerThe Central System can use TriggerMessage.req to request the Charge Point to send a FirmwareStatusNotification or DiagnosticsStatusNotification on demand. The requestedMessage field uses the MessageTrigger enum.
TriggerMessage.req (Central System -> Charge Point)
| Field | Type | Required | Description |
|---|---|---|---|
requestedMessage | MessageTrigger (enum) | Yes | The type of Charge Point-initiated message that the Central System wishes to receive. |
connectorId | integer (connectorId > 0) | No | Only filled in when request applies to a specific connector. If absent and the message is connector-relevant, interpreted as "for all allowed connectorId values". |
MessageTrigger Enum Values
| Value | Description |
|---|---|
BootNotification | To trigger a BootNotification request |
DiagnosticsStatusNotification | To trigger a DiagnosticsStatusNotification request |
FirmwareStatusNotification | To trigger a FirmwareStatusNotification request |
Heartbeat | To trigger a Heartbeat request |
MeterValues | To trigger a MeterValues request |
StatusNotification | To trigger a StatusNotification request |
Note: StartTransaction and StopTransaction have been left out of this mechanism because they are not state related, but by their nature
describe a transition.
{
"type": "object",
"properties": {
"requestedMessage": {
"type": "string",
"enum": [
"BootNotification",
"DiagnosticsStatusNotification",
"FirmwareStatusNotification",
"Heartbeat",
"MeterValues",
"StatusNotification"
]
},
"connectorId": {
"type": "integer"
}
},
"additionalProperties": false,
"required": ["requestedMessage"]
}[2, "msg-005", "TriggerMessage", {
"requestedMessage": "FirmwareStatusNotification"
}]TriggerMessage.conf (Charge Point -> Central System)
| Field | Type | Required | Description |
|---|---|---|---|
status | TriggerMessageStatus (enum) | Yes | Indicates whether the Charge Point will send the requested notification or not. |
TriggerMessageStatus Enum Values
| Status | Meaning |
|---|---|
Accepted | Requested notification will be sent. |
Rejected | Requested notification will not be sent. |
NotImplemented | Requested notification cannot be sent because it is either not implemented or unknown. |
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"Accepted",
"Rejected",
"NotImplemented"
]
}
},
"additionalProperties": false,
"required": ["status"]
}[3, "msg-005", {
"status": "Accepted"
}]Behavioral Rules
- The Charge Point SHALL first send the
TriggerMessageresponse, before sending the requested message. - Messages that the Charge Point marks as accepted SHOULD be sent. The situation could occur that, between accepting the request and actually sending the requested message, that same message gets sent because of normal operations. In such cases the message just sent MAY be considered as complying with the request.
- The TriggerMessage mechanism is not intended to retrieve historic data. The messages it triggers should only give current information.
- The CP will respond with
status: Idlefor bothFirmwareStatusNotificationandDiagnosticsStatusNotificationif no operation is in progress. StartTransactionandStopTransactionhave been left out of this mechanism because they are not state related, but by their nature describe a transition.- The
connectorIdfield is not relevant toFirmwareStatusNotificationorDiagnosticsStatusNotificationtriggers -- it SHALL be ignored if provided. These are Charge Point-level operations, not connector-specific.
Use Cases
TriggerMessage is useful when:
After Reconnection
The Central System has lost track of progress (e.g., after reconnection)
Status Polling
The Central System wants to poll current firmware update or diagnostics upload status
Stalled Updates
A firmware update is in progress and the last status notification was received much longer ago than could reasonably be expected
6. CSMS (Central System) Implementation Notes
ImplementationHandling UpdateFirmware
- Sending the request: Build an
UpdateFirmware.reqwith a valid firmware download URI and aretrieveDate(use a future time if you want to schedule the update during off-peak hours). - Response: The
UpdateFirmware.confis always empty -- there is no acceptance/rejection mechanism. The CP always acknowledges. Failures are communicated asynchronously viaFirmwareStatusNotification. - Tracking progress: Listen for incoming
FirmwareStatusNotification.reqmessages from the CP and respond with emptyFirmwareStatusNotification.conf. - Post-install reboot: After receiving
status: Installed, you may need to send aReset.req(Hard)if the CP does not reboot automatically. - Verify new firmware: After reboot, the CP will
send a
BootNotification.req-- check thefirmwareVersionfield (CiString50Type, optional) to confirm the update succeeded.
Handling GetDiagnostics
- Sending the request: Build a
GetDiagnostics.reqwith a URI (directory) where the CP should upload the file. Optionally specifystartTime/stopTimeto narrow the log window. - Response: Check
GetDiagnostics.conffor afileName-- if this field is not present, no diagnostics information is available. - Single file: The Charge Point SHALL upload a single file. The format of the diagnostics file is not prescribed by the specification.
- Tracking progress: Listen for incoming
DiagnosticsStatusNotification.reqmessages and respond with emptyDiagnosticsStatusNotification.conf. - Retrieving the file: After receiving
status: Uploaded, retrieve the file from the upload location you specified.
Handling Incoming Status Notifications
For both FirmwareStatusNotification.req and DiagnosticsStatusNotification.req:
- The Central System SHALL respond with the respective empty
.confmessage. - Log/store the status for tracking and UI display.
- The
Idlestatus SHALL only be sent in response to aTriggerMessage.req-- it means the CP is not currently busy with the respective operation.
7. Related Configuration Keys
ConfigThese configuration keys on the Charge Point are relevant to firmware and diagnostics operations.
| Key | Req/Opt | Type | Access | Description |
|---|---|---|---|---|
SupportedFeatureProfiles | required | CSL | R | A list of supported Feature Profiles. Possible profile identifiers: Core, FirmwareManagement, LocalAuthListManagement, Reservation, SmartCharging and RemoteTrigger. Contains "FirmwareManagement" if this profile is supported. |
SupportedFeatureProfilesMaxLength | optional | integer | R | Maximum number of items in the SupportedFeatureProfiles configuration key. |
SupportedFileTransferProtocols | -- | CSL | R | Comma-separated list of supported file transfer protocols: FTP, FTPS, HTTP, HTTPS. Controls which protocols the Charge Point supports for firmware download and diagnostics upload. |
8. Key Implementation Considerations
ReferenceFirmware URI must include the protocol
The CP uses this to determine the download method (FTP, FTPS, HTTP, HTTPS). The URL also contains the protocol which must be used to download the firmware.
Diagnostics URI is a directory
The CP decides the filename and reports it back in GetDiagnostics.conf. The Charge Point SHALL upload a single file; format is not prescribed.
Resume support (download)
FTP(S) is better optimized for large binary data and has the ability to resume downloads. In case a download is interrupted, the Charge Point can resume downloading after the part it already has downloaded.
Resume support (upload)
FTP(S) has the ability to resume uploads. In case an upload is interrupted, the Charge Point can resume uploading after the part it already has uploaded.
No rejection mechanism for UpdateFirmware
The CP always accepts the request. Failures are communicated asynchronously via FirmwareStatusNotification.
Transaction safety
If it is not possible to continue charging during firmware installation, it is recommended to wait until the Charging Session has ended before commencing installation. Set connectors not in use to UNAVAILABLE while waiting.
Retry parameters are hints
If retries/retryInterval are omitted, the CP decides its own retry policy.
Time format
All dateTime fields MUST use ISO 8601 date time notation. Message receivers must be able to handle fractional seconds and time zone offsets. UTC is strongly recommended for interoperability.
FirmwareStatusNotification is mandatory during update
The CP MUST send these to keep the CSMS informed of progress.
DiagnosticsStatusNotification is mandatory during upload
The CP MUST send DiagnosticsStatusNotification.req PDUs to keep the Central System updated with the status of the upload process.
Idle status is TriggerMessage-only
For both FirmwareStatus and DiagnosticsStatus, the Idle value SHALL only be used in a notification that was triggered by a TriggerMessage.req, not during normal operation flows.
Digital signing
To ensure that the correct firmware is downloaded, it is recommended that the firmware is also digitally signed.