Availability Flows - CSMS Developer Guide
Based on OCPP 2.0.1 Edition 4 Specification (Part 2), Section G (pages 193–203). This guide covers all availability flows (G01–G05) from the CSMS perspective.
1. Overview
IntroductionSection G specifies how the Charging Station informs the CSMS about its current availability for starting new transactions. This covers status reporting, availability control, and fault reporting.
Status Reporting (G01, G02)
The Charging Station informs the CSMS about connector status changes and proves it is still alive via heartbeats.
Availability Control (G03, G04)
The CSMS changes the operational availability of individual EVSEs/Connectors or the entire Charging Station.
Fault Reporting (G05)
The Charging Station reports connector lock failures to the CSMS.
OCPP Message Direction Convention
| Direction | Meaning |
|---|---|
CS → CSMS | Charging Station sends a CALL (request) to the CSMS |
CSMS → CS | CSMS sends a CALL (request) to the Charging Station |
G01, G02, G05 are CS-initiated — the Charging Station sends
the request to the CSMS.
G03, G04 are CSMS-initiated — the CSMS sends the request to
the Charging Station.
Connector Status Model
A Charging Station Connector MUST have one of these statuses (ConnectorStatusEnumType):
| Status | Description |
|---|---|
Available | Connector is ready and no EV is connected |
Occupied | An EV is connected (cable plugged in) |
Reserved | Connector is reserved for a specific IdToken |
Unavailable | Connector is not available for new transactions (maintenance, set via ChangeAvailabilityRequest, firmware update, etc.) |
Faulted | Connector has an error/fault condition |
State Transition Overview (connecting/disconnecting)
| Initial State | Cable Plugin | Cable Unplug |
|---|---|---|
Available | → Occupied | — |
Occupied | — | → Available (or → Unavailable if scheduled) |
Reserved | — (stays Reserved unless matching IdToken) | — |
Unavailable | — | — |
Faulted | — | — |
2. G01 — Status Notification
CS → CSMSThe Charging Station sends a StatusNotificationRequest to inform the CSMS about a Connector status change. This is the primary mechanism
for the CSMS to track the real-time state of every connector on every EVSE.
Alternative: Instead of StatusNotificationRequest, the CS can send a NotifyEventRequest with trigger=Delta, component.name="Connector", variable="AvailabilityState". Both are valid — the spec recommends StatusNotificationRequest for now.
Sequence (CSMS perspective)
Charging Station CSMS
| |
| [connector status changes] |
| |
|-- StatusNotificationRequest ------------------->| (evseId, connectorId,
| (timestamp, connectorStatus) | connectorStatus)
| |
|<- StatusNotificationResponse -------------------| (empty body)
| |Alternative flow using NotifyEventRequest:
Charging Station CSMS
| |
| [connector status changes] |
| |
|-- NotifyEventRequest -------------------------->| (component="Connector",
| (trigger=Delta, variable="AvailabilityState", | EVSE id in evse.id,
| actualValue="Occupied") | connector in evse.connectorId)
| |
|<- NotifyEventResponse --------------------------| (empty body)
| |Handle StatusNotificationRequest
Message: StatusNotificationRequest (CS → CSMS)
| Field | Type | Required | Description |
|---|---|---|---|
timestamp | dateTime (RFC 3339) | Required | Time at which the status change occurred. |
connectorStatus | ConnectorStatusEnumType | Required | New status: Available, Occupied, Reserved, Unavailable, Faulted. |
evseId | integer | Required | EVSE identifier (> 0). |
connectorId | integer | Required | Connector identifier within the EVSE. |
customData | CustomDataType | Optional | Custom vendor data. |
CSMS handling logic:
- Store the connector status — update the internal database record for
(charge_point_id, evse_id, connector_id)with the newconnectorStatusandtimestamp. - Track EVSE-level availability — when one connector on a multi-connector EVSE
becomes
OccupiedorReserved, the CSMS should consider that the other connectors on the same EVSE are no longer usable (the CS SHOULD NOT send a status change for the other connectors per G01.FR.08). - Handle
Faultedstatus — flag the connector for operator attention and exclude it from available connector searches. - Handle
Unavailablestatus — if set by aChangeAvailabilityRequest, this status MUST be persistent across reboots (G01.FR.02).
Send StatusNotificationResponse
Message: StatusNotificationResponse (CSMS → CS) — the response body is empty. Just send {} as the payload.
{}Handle alternative NotifyEventRequest for connector
status
If the CS sends connector status changes via NotifyEventRequest instead:
| EventData Field | Expected Value |
|---|---|
component.name | "Connector" |
component.evse.id | EVSE number |
component.evse.connectorId | Connector number within EVSE |
variable.name | "AvailabilityState" |
trigger | "Delta" |
actualValue | "Available", "Occupied", "Reserved", "Unavailable", "Faulted" |
Optionally, the CS may also include component-level events: component = "EVSE" with variable = "AvailabilityState" for EVSE-level status, or component = "ChargingStation" for station-level status. Respond with an empty NotifyEventResponse ({}).
Requirements Reference (G01)
| ID | Summary | CSMS Impact |
|---|---|---|
G01.FR.01 | Connector MUST have a valid ConnectorStatusEnumType value | Validate incoming status values |
G01.FR.02 | Unavailable set by ChangeAvailabilityRequest persists across reboots | Track which connectors were set Unavailable by CSMS command |
G01.FR.03 | CS sends status change when Available connector gets EV connected → Occupied | Update connector status to Occupied |
G01.FR.04 | CS sends status when Occupied connector gets EV disconnected → Available (if not scheduled Unavailable) | Update connector status to Available |
G01.FR.05 | CS sends status when Occupied connector gets EV disconnected → Unavailable (if scheduled) | Update connector status to Unavailable |
G01.FR.06 | CS sends status when Reserved connector gets matching EV connected → Occupied | Update connector status to Occupied |
G01.FR.07 | CS sends status change when ChangeAvailabilityRequest leads to a connector status change | Update connector status accordingly |
G01.FR.08 | CS SHOULD NOT send status for other connectors on same EVSE when one is plugged in | CSMS must infer multi-connector EVSE unavailability |
G01.FR.09 | Reserved connector stays Reserved when EV connects without matching IdToken | Do NOT update status for non-matching connections |
3. G02 — Heartbeat
CS → CSMSThe Charging Station periodically sends HeartbeatRequest messages to let the CSMS know it is still connected and alive. The CSMS responds with the current
time, which the CS can use for clock synchronization.
Prerequisite: Heartbeat interval is set (configured via BootNotificationResponse.interval).
Sequence (CSMS perspective)
Charging Station CSMS
| |
| [heartbeat interval elapsed] |
| |
|-- HeartbeatRequest ---------------------------->| (empty body)
| |
|<- HeartbeatResponse ----------------------------| (currentTime)
| |Handle HeartbeatRequest
Message: HeartbeatRequest (CS →
CSMS) — the request body is empty (no required fields beyond optional customData).
CSMS handling logic:
- Update last-seen timestamp — record the current time as the last contact time for this Charging Station. This is used for online/offline detection.
- Assume availability — per G02.FR.04, whenever ANY message is received from a CS (not just heartbeats), the CSMS SHALL assume that CS is available/online.
Send HeartbeatResponse
Message: HeartbeatResponse (CSMS
→ CS)
| Field | Type | Required | Description |
|---|---|---|---|
currentTime | dateTime (RFC 3339) | Required | The current time of the CSMS. Used by the CS for clock synchronization. |
customData | CustomDataType | Optional | Custom vendor data. |
{
"currentTime": "2024-01-15T10:30:00.000Z"
}Offline Detection
The CSMS should implement offline detection logic:
When to consider CS Offline
If no message (heartbeat or otherwise) is received from a CS within a timeout period (e.g., heartbeat_interval × 2 or heartbeat_interval + grace_period), consider the CS Offline.
Actions when CS goes offline
- Flag the Charging Station as offline in the database
- Optionally notify operators/monitoring systems
- Stop sending CSMS-initiated requests to this CS (they will fail/timeout)
Requirements Reference (G02)
| ID | Summary | CSMS Impact |
|---|---|---|
G02.FR.01 | CS adjusts heartbeat interval from BootNotificationResponse | Set interval in BootNotificationResponse |
G02.FR.02 | CS sends HeartbeatRequest after configurable interval | Expect periodic heartbeats |
G02.FR.03 | HeartbeatResponse SHALL contain CSMS current time | Always include currentTime |
G02.FR.04 | ANY message from CS = CS is alive | Update last-seen on every message, not just heartbeats |
G02.FR.05 | CS RECOMMENDED to reset heartbeat timer on any message sent | Heartbeats may be less frequent if CS sends other messages |
G02.FR.06 | CS RECOMMENDED to sync clock from HeartbeatResponse | Provide accurate UTC time |
G02.FR.07 | If heartbeat timer continuously reset, CS should send heartbeat at least every 24h | At minimum expect one heartbeat per 24h |
4. G03 — Change Availability EVSE/Connector
CSMS → CSThe CSMS sends a ChangeAvailabilityRequest to change the operational availability of a specific EVSE or Connector to either Operative (allow charging)
or Inoperative (block charging).
Use cases: Taking an EVSE offline for maintenance, re-enabling after repair, disabling a broken connector reported by a customer.
Prerequisite: Active WebSocket connection between CSMS and Charging Station.
Sequence (CSMS perspective)
Charging Station CSMS
| |
| [operator triggers change] |
| |
|<- ChangeAvailabilityRequest --------------------| (evse.id, evse.connectorId,
| (operationalStatus=Inoperative) | operationalStatus)
| |
|-- ChangeAvailabilityResponse ------------------>| (status=Accepted/Rejected/Scheduled)
| |
| [if availability changed] |
| |
| [if transaction ongoing → wait for finish] |
| |
| [for all affected connectors:] |
|-- StatusNotificationRequest ------------------->| (connectorStatus=Unavailable)
|<- StatusNotificationResponse -------------------|
| |Send ChangeAvailabilityRequest
Message: ChangeAvailabilityRequest (CSMS → CS)
| Field | Type | Required | Description |
|---|---|---|---|
operationalStatus | OperationalStatusEnumType | Yes | Operative or Inoperative |
evse | EVSEType | Yes (for G03) | Identifies the target EVSE and optionally a specific connector |
customData | CustomDataType | Optional | Custom vendor data |
OperationalStatusEnumType
Operative EVSE/Connector is available for charging. Connector status becomes Available, Occupied, or Reserved.
Inoperative EVSE/Connector is NOT available for charging. Connector status becomes Unavailable.
EVSEType Targeting Rules
Specific Connector: Set evse.id AND evse.connectorId
Entire EVSE: Set only evse.id (omit connectorId)
{
"operationalStatus": "Inoperative",
"evse": {
"id": 1
}
}{
"operationalStatus": "Operative",
"evse": {
"id": 2,
"connectorId": 1
}
}Handle ChangeAvailabilityResponse
| Value | Description | CSMS Action |
|---|---|---|
Accepted | CS accepted and applied the change immediately | Update internal status; expect StatusNotificationRequest for affected connectors |
Rejected | CS could not apply the change | Log failure; retry or investigate |
Scheduled | A transaction is currently in progress; change will apply after transaction finishes | Mark the pending change; wait for StatusNotificationRequest after transaction ends |
After accepting, the CS will send StatusNotificationRequest for each affected connector:
- When set to Inoperative: All operative connectors (not
Faulted) on the targeted EVSE becomeUnavailable(G03.FR.06) - When set back to Operative: Connectors revert to their original status (G03.FR.07)
Important Notes
Persistence: The availability state set by ChangeAvailabilityRequest MUST be persistent across reboot/power loss (G03.FR.08).
Already in requested state: If the CS is already in the requested state,
it responds with Accepted (G03.FR.03).
Independent states: Charging Station, EVSEs, and Connectors have separate individual states. Setting a Connector to Inoperative, then the EVSE to Inoperative, then the EVSE back to Operative — the Connector will remain Inoperative.
Reserved connectors: If a connector is Reserved and an EV
connects without a matching IdToken, the connector status SHALL NOT change (G03.FR.09).
Requirements Reference (G03)
| ID | Summary | CSMS Impact |
|---|---|---|
G03.FR.01 | CS SHALL respond with ChangeAvailabilityResponse | Expect a response |
G03.FR.02 | Response indicates whether CS can change availability | Handle all 3 status values |
G03.FR.03 | If already in requested state → Accepted | Don't treat as error |
G03.FR.04 | CS informs CSMS of new connector status via StatusNotificationRequest or NotifyEventRequest | Process follow-up status messages |
G03.FR.05 | If transaction ongoing → Scheduled, change after transaction | Track scheduled changes |
G03.FR.06 | When EVSE becomes Inoperative, all operative (non-Faulted) connectors → Unavailable | Expect multiple status notifications |
G03.FR.07 | When EVSE becomes Operative, connectors revert to original status | Expect status restoration |
G03.FR.08 | Set availability state is persistent across reboot/power loss | State survives resets |
G03.FR.09 | Reserved connector stays Reserved when EV connects without matching IdToken | No status change expected |
5. G04 — Change Availability Charging Station
CSMS → CSThe CSMS sends a ChangeAvailabilityRequest without an evse field to change the operational availability of the entire Charging Station. This affects
all EVSEs and all Connectors on the station.
This is a parent use case of G03, using the same messages but targeting the whole station. Use cases: Taking an entire station offline for maintenance, disabling a station being decommissioned, re-enabling after repairs.
Sequence (CSMS perspective)
Charging Station CSMS
| |
| [operator triggers change] |
| |
|<- ChangeAvailabilityRequest --------------------| (operationalStatus, NO evse field)
| (operationalStatus=Inoperative) |
| |
|-- ChangeAvailabilityResponse ------------------>| (status=Accepted/Rejected/Scheduled)
| |
| [if availability changed] |
| |
| [if any transaction ongoing → wait for finish] |
| |
| [for ALL connectors on ALL EVSEs:] |
|-- StatusNotificationRequest ------------------->| (connectorStatus=Unavailable)
|<- StatusNotificationResponse -------------------|
|-- StatusNotificationRequest ------------------->| (next connector...)
|<- StatusNotificationResponse -------------------|
| ... |
| |Send ChangeAvailabilityRequest (Station-level)
Key difference from G03: Do NOT include the evse field — this signals
a station-level change (G04.FR.01).
| Field | Type | Required | Description |
|---|---|---|---|
operationalStatus | OperationalStatusEnumType | Required | Operative or Inoperative |
evse | EVSEType | Omit | Do NOT include the evse field — this signals a station-level change (G04.FR.01) |
customData | CustomDataType | Optional | Custom vendor data |
{
"operationalStatus": "Inoperative"
}{
"operationalStatus": "Operative"
}Handle ChangeAvailabilityResponse
| Value | Description | CSMS Action |
|---|---|---|
Accepted | CS accepted and applied the change | Expect StatusNotificationRequest for ALL connectors |
Rejected | CS could not apply the change | Log failure |
Scheduled | A transaction is in progress on one or more EVSEs; change will apply after all transactions finish | Wait for deferred status notifications |
CSMS handling logic:
- Accepted: Expect
StatusNotificationRequestfor every connector on every EVSE. When station is setInoperative, all operative EVSEs and connectors (notFaulted) becomeUnavailable(G04.FR.07). - Scheduled: At least one EVSE has an active transaction. The change will be applied after all transactions complete. Track the pending change.
- Back to Operative: All EVSEs and connectors revert to their original/actual status (G04.FR.08). Update records for each incoming status notification.
Important Notes
Distinguishing G03 vs G04: The difference is the presence/absence of the evse field in ChangeAvailabilityRequest:
• evse field present → G03 (EVSE/Connector level)
• evse field omitted → G04 (entire Charging Station)
Persistence: Set availability state persists across reboot/power loss (G04.FR.09).
Independent states: Even after setting the whole station back to Operative, individual
EVSEs/Connectors that were independently set to Inoperative (via G03)
remain Inoperative.
Requirements Reference (G04)
| ID | Summary | CSMS Impact |
|---|---|---|
G04.FR.01 | If evse field is omitted → change applies to entire station | Omit evse for station-level changes |
G04.FR.02 | CS SHALL respond with ChangeAvailabilityResponse | Expect a response |
G04.FR.03 | Response indicates ability to change | Handle all 3 status values |
G04.FR.04 | Already in requested state → Accepted | Don't treat as error |
G04.FR.05 | CS informs CSMS of each changed connector via StatusNotificationRequest or NotifyEventRequest | Expect multiple status notifications |
G04.FR.06 | If any transaction in progress → Scheduled | Track deferred changes |
G04.FR.07 | When station becomes Inoperative, all operative (non-Faulted) EVSEs and connectors → Unavailable | Expect all connectors to become Unavailable |
G04.FR.08 | When station becomes Operative, all EVSEs and connectors revert to original status | Expect all connectors to restore original status |
G04.FR.09 | Set availability state is persistent across reboot/power loss | State survives resets |
6. G05 — Lock Failure
CS → CSMSThe Charging Station reports to the CSMS when the connector retention lock fails to engage properly. This prevents the EV Driver from starting a charge session because the cable cannot be properly locked, which is a safety concern.
Safety Note: The CS SHALL NOT start charging when the lock fails (G05.FR.01).
The CS reports this via NotifyEventRequest — not StatusNotificationRequest.
Prerequisites:
- Charging cable is plugged in (connector status = Occupied)
- The Charging Station has the
ConnectorPlugRetentionLockcomponent defined in its Device Model MonitoringLevelis set to a level that reports connector lock event failures
Sequence (CSMS perspective)
User Charging Station CSMS
| | |
|-- plug in cable -->| |
| | [user authorization successful] |
| | |
| | [lock connector attempt FAILS] |
| | |
| |-- NotifyEventRequest -------------->|
| | (component=ConnectorPlugRetention |
| | Lock, variable=Problem, |
| | value=true) |
| | |
| |<- NotifyEventResponse --------------| (empty body)
| | |
| [opt: notify user | |
| "cable cannot | |
| be locked"] | |
| | |Handle NotifyEventRequest (Lock Failure)
For a lock failure, the CS sends a NotifyEventRequest with
an eventData entry containing:
| EventData Field | Expected Value | Description |
|---|---|---|
eventId | integer | Unique event identifier |
timestamp | dateTime | Time of the lock failure |
trigger | "Delta" | State change trigger |
actualValue | "true" | The problem occurred |
component.name | "ConnectorPlugRetentionLock" | The lock component |
component.evse.id | integer | EVSE where the lock failed |
component.evse.connectorId | integer | Connector where the lock failed |
variable.name | "Problem" | Indicates a problem with the component |
eventNotificationType | "HardWiredNotification" or other | Type of event notification |
CSMS handling logic:
- Identify the lock failure — check if
component.name == "ConnectorPlugRetentionLock"andvariable.name == "Problem"andactualValue == "true". - Record the failure — store the lock failure event, associated EVSE/Connector, and timestamp.
- Alert the operator — a lock failure is a safety issue and should be flagged for maintenance attention. The connector cannot safely charge if the cable cannot be locked.
- Note: The transaction is NOT started — the CS SHALL NOT start charging when
the lock fails (G05.FR.01). No
TransactionEventRequest(Started)will be received.
Response: NotifyEventResponse (CSMS
→ CS) — the response body is empty.
{
"generatedAt": "2024-01-15T10:30:00.000Z",
"seqNo": 0,
"tbc": false,
"eventData": [
{
"eventId": 1,
"timestamp": "2024-01-15T10:30:00.000Z",
"trigger": "Delta",
"actualValue": "true",
"eventNotificationType": "HardWiredNotification",
"component": {
"name": "ConnectorPlugRetentionLock",
"evse": {
"id": 1,
"connectorId": 1
}
},
"variable": {
"name": "Problem"
}
}
]
}{}Requirements Reference (G05)
| ID | Summary | CSMS Impact |
|---|---|---|
G05.FR.01 | CS SHALL NOT start charging when lock fails | No transaction should start — CSMS won't receive TransactionEventRequest(Started) |
G05.FR.02 | CS SHALL send NotifyEventRequest for ConnectorPlugRetentionLock component with variable=Problem, value=true | Detect and store lock failure events |
G05.FR.03 | CSMS SHALL respond with NotifyEventResponse | Always respond with empty body |
G05.FR.04 | CS MAY show optional notification to EV Driver | No CSMS action needed |
7. Message Schema Reference
SchemasCommon Types
CustomDataType (optional on all messages — omitted from
schemas below for brevity)
| Field | Type | Required | Description |
|---|---|---|---|
vendorId | string (max 255) | Required | Vendor identifier for the custom data |
StatusInfoType
| Field | Type | Required | Description |
|---|---|---|---|
reasonCode | string (max 20) | Required | Predefined code for the reason (case-insensitive) |
additionalInfo | string (max 512) | Optional | Additional text with detailed information |
EVSEType
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | Required | EVSE identifier (> 0) |
connectorId | integer | Optional | Connector index number within the EVSE |
Messages Used in Section G (by flow)
| Flow | Direction | Request Message | Response Message |
|---|---|---|---|
| G01 | CS → CSMS | StatusNotificationRequest | StatusNotificationResponse |
| G01 (alt) | CS → CSMS | NotifyEventRequest | NotifyEventResponse |
| G02 | CS → CSMS | HeartbeatRequest | HeartbeatResponse |
| G03 | CSMS → CS | ChangeAvailabilityRequest | ChangeAvailabilityResponse |
| G04 | CSMS → CS | ChangeAvailabilityRequest | ChangeAvailabilityResponse |
| G05 | CS → CSMS | NotifyEventRequest | NotifyEventResponse |
StatusNotification Schemas
{
"timestamp": "2024-01-15T10:30:00.000Z", // required, dateTime
"connectorStatus": "Available", // required, ConnectorStatusEnumType
"evseId": 1, // required, integer
"connectorId": 1 // required, integer
}{}ConnectorStatusEnumType: "Available" | "Occupied" | "Reserved" | "Unavailable" | "Faulted"
Heartbeat Schemas
{}{
"currentTime": "2024-01-15T10:30:00.000Z" // required, dateTime
}ChangeAvailability Schemas
{
"operationalStatus": "Inoperative", // required, OperationalStatusEnumType
"evse": { // optional (omit for station-level G04)
"id": 1, // required, integer (> 0)
"connectorId": 1 // optional, integer (omit for EVSE-level)
}
}{
"status": "Accepted", // required, ChangeAvailabilityStatusEnumType
"statusInfo": { // optional
"reasonCode": "string", // required (max 20), case-insensitive
"additionalInfo": "string" // optional (max 512)
}
}OperationalStatusEnumType: "Inoperative" | "Operative"
ChangeAvailabilityStatusEnumType: "Accepted" | "Rejected" | "Scheduled"
| Target | evse field | evse.id | evse.connectorId |
|---|---|---|---|
| Entire Station (G04) | omitted | — | — |
| Specific EVSE (G03) | present | set | omitted |
| Specific Connector (G03) | present | set | set |
NotifyEvent Schemas
{
"generatedAt": "2024-01-15T10:30:00.000Z", // required, dateTime
"seqNo": 0, // required, integer
"tbc": false, // optional, boolean (default: false)
"eventData": [ // required, array (min 1 item)
{
"eventId": 1, // required, integer
"timestamp": "2024-01-15T10:30:00.000Z", // required, dateTime
"trigger": "Delta", // required, EventTriggerEnumType
"actualValue": "true", // required, string (max 2500)
"eventNotificationType": "HardWiredNotification",
"component": { // required, ComponentType
"name": "ConnectorPlugRetentionLock", // required, string (max 50)
"instance": null, // optional, string (max 50)
"evse": { // optional, EVSEType
"id": 1,
"connectorId": 1
}
},
"variable": { // required, VariableType
"name": "Problem", // required, string (max 50)
"instance": null
},
"cause": null,
"cleared": false,
"techCode": null,
"techInfo": null,
"transactionId": null,
"variableMonitoringId": null
}
]
}{}Enum Types
EventTriggerEnumType:
"Alerting" | "Delta" | "Periodic"
EventNotificationEnumType:
"HardWiredNotification" | "HardWiredMonitor" | "PreconfiguredMonitor" | "CustomMonitor"
Database Schema Suggestions
To support Section G flows, the CSMS should maintain these data structures:
connector_status table
| Column | Type | Description |
|---|---|---|
charge_point_id | UUID | FK to charge point |
evse_id | INTEGER | EVSE number |
connector_id | INTEGER | Connector number |
status | TEXT/ENUM | Available, Occupied, Reserved, Unavailable, Faulted |
timestamp | TIMESTAMPTZ | When the status was last reported |
updated_at | TIMESTAMPTZ | When the CSMS received the update |
charge_point_availability table (for tracking CSMS-initiated changes)
| Column | Type | Description |
|---|---|---|
charge_point_id | UUID | FK to charge point |
evse_id | INTEGER | Null = station-level |
connector_id | INTEGER | Null = EVSE-level |
operational_status | TEXT/ENUM | Operative, Inoperative |
change_status | TEXT/ENUM | Accepted, Scheduled, Rejected |
requested_at | TIMESTAMPTZ | When the CSMS sent the request |
charge_point_heartbeat / last_seen tracking
| Column | Type | Description |
|---|---|---|
charge_point_id | UUID | FK to charge point |
last_seen_at | TIMESTAMPTZ | Last time any message was received from this CS |
is_online | BOOLEAN | Whether the CS is considered online |
Implementation Checklist
Status Notification
- Handle StatusNotificationRequest — parse and store connector status
- Handle alternative NotifyEventRequest for connector status changes
- Send empty StatusNotificationResponse body
- Infer EVSE-level availability when one connector on multi-connector EVSE becomes occupied
Heartbeat
- Handle HeartbeatRequest — update last-seen timestamp
- Send HeartbeatResponse with accurate currentTime in UTC
- Implement offline detection (timeout-based)
- Update last-seen on ANY message received (not just heartbeats)
Change Availability EVSE/Connector
- Implement ChangeAvailabilityRequest builder with EVSE/Connector targeting
- Handle ChangeAvailabilityResponse with all 3 status values
- Track Scheduled changes and resolve when subsequent StatusNotificationRequest arrives
- Handle follow-up StatusNotificationRequest messages for affected connectors
Change Availability Charging Station
- Implement ChangeAvailabilityRequest builder WITHOUT evse field for station-level
- Handle response and track pending changes across all connectors
- Handle bulk StatusNotificationRequest messages for all connectors
Lock Failure
- Handle NotifyEventRequest — detect ConnectorPlugRetentionLock / Problem / true pattern
- Send empty NotifyEventResponse
- Record lock failure events and alert operators