DRAFT — not indexed by search engines. Visible only via direct URL or the admin page.

OCPP StatusNotification: The Charger State Machine

StatusNotification carries every connector state change. The state machine, the transitions that matter, and what operational dashboards depend on.

StatusNotification is the message that keeps the CSMS’s view of each charger in sync with reality. Every state change on every connector fires a StatusNotification. The CSMS uses these to drive operational dashboards, monitoring, alerts, and session-start eligibility. If you’re new to the protocol, start with what is OCPP for the overall message model.

It’s a small message but operationally critical. This article covers the state machine it represents, the transitions, and the common issues that come up in production.

The basic structure (OCPP 1.6)

{
  "connectorId": 1,
  "errorCode": "NoError",
  "status": "Charging",
  "timestamp": "2026-06-27T14:30:00Z",
  "info": null,
  "vendorId": null,
  "vendorErrorCode": null
}

The fields:

  • connectorId — which connector. 0 means the whole charger; 1+ is per-connector.
  • errorCode — current fault state (NoError if no fault).
  • status — operational state.
  • timestamp — when the state changed.
  • info — optional human-readable info.
  • vendorId / vendorErrorCode — vendor-specific error context.

The status states (OCPP 1.6)

Connector status can be:

  • Available — ready for a user.
  • Preparing — user is plugging in / preparing to start a session.
  • Charging — actively delivering energy.
  • SuspendedEVSE — paused by the EVSE (e.g. smart-charging throttle, grid command).
  • SuspendedEV — paused by the EV (battery management or temperature).
  • Finishing — session ending; user about to unplug.
  • Reserved — connector reserved for a specific user via ReserveNow.
  • Unavailable — admin-disabled or not operational for non-fault reasons.
  • Faulted — a fault is preventing operation. Combined with errorCode for detail.

The state machine

A normal session moves through states like this:

Available
    ↓ (user plugs in cable)
Preparing
    ↓ (authorization complete, vehicle handshake done)
Charging
    ↓ (rate changes, smart charging, temperature)
SuspendedEVSE / SuspendedEV (may oscillate during session)
    ↓ (session ends)
Finishing
    ↓ (user unplugs)
Available

The same flow as a state diagram:

stateDiagram-v2
    [*] --> Available
    Available --> Preparing: cable in
    Available --> Reserved: ReserveNow
    Reserved --> Preparing: user arrives
    Reserved --> Available: expired
    Preparing --> Charging: auth done
    Charging --> SuspendedEVSE: EVSE pause
    Charging --> SuspendedEV: EV pause
    SuspendedEVSE --> Charging: resume
    SuspendedEV --> Charging: resume
    Charging --> Finishing: session ends
    Finishing --> Available: unplug
    Charging --> Faulted: fault
    Faulted --> Available: cleared

A faulted session can move to Faulted at any point. A reservation creates a transition Available → Reserved.

Not every implementation fires StatusNotification on every internal state change. Most fire on:

  • Available ↔ Preparing
  • Preparing → Charging
  • Charging ↔ Suspended states
  • → Finishing
  • Any transition involving Faulted, Reserved, or Unavailable

Some chargers under-report (fewer StatusNotifications, harder to track session state). Some over-report (StatusNotification flood during state-machine oscillation).

OCPP 2.0.1: device-model based status

OCPP 2.0.1 uses the device model. Status comes from variables on EVSE and Connector components.

A change in OperationalStatus on EVSE 1 triggers a StatusNotificationRequest:

{
  "evseId": 1,
  "connectorId": 1,
  "connectorStatus": "Occupied",
  "timestamp": "2026-06-27T14:30:00Z"
}

The states in 2.0.1 are slightly different:

  • Available — same as 1.6.
  • Occupied — connected to a vehicle (replaces some 1.6 states).
  • Reserved — same.
  • Unavailable — same.
  • Faulted — same.

Plus more granular states are exposed via additional variables (chargingState within the transaction, availability state, etc.).

The 2.0.1 model gives a richer state picture but requires CSMS-side handling to map variable changes to status display.

Common transition patterns

A few real-world transition sequences and what they tell you.

Normal session

Available → Preparing → Charging → Finishing → Available

The happy path. User plugs in, charges, unplugs. Maybe with a few Charging ↔ SuspendedEV oscillations as the battery’s BMS throttles.

Reserved session (fulfilled)

Available → Reserved → Preparing → Charging → Finishing → Available

User reserved the charger, arrived, plugged in, charged. The Reserved → Preparing transition is the reservation being fulfilled.

Reserved session (no-show)

Available → Reserved → Available

Reservation expired without a user arriving. The charger auto-released.

Faulted session

Available → Preparing → Charging → Faulted → Available

A fault occurred mid-session. Session ended. After fault cleared (or manual reset), back to Available.

Faulted on plug-in

Available → Preparing → Faulted → Available

User plugged in but the charger detected a fault (likely ConnectorLockFailure or EVCommunicationError). Session never started. These fault codes are covered in common OCPP errors explained (coming soon).

Long pause

Available → Preparing → Charging → SuspendedEVSE [for 30 min] → Charging → Finishing → Available

The session was paused by the EVSE for a long time. Possibly demand-response curtailment, possibly smart-charging schedule. The user may not have noticed; the EV did.

Why StatusNotification matters

The CSMS uses StatusNotification for many things.

Operational dashboard. “Where are all my chargers, what’s their current state?”

Availability for reservations. Reserving a Faulted or Unavailable charger doesn’t make sense.

Alert generation. A charger that transitioned to Faulted should alert operations.

Per-station fault history. A connector frequently going to Faulted needs maintenance.

Session lifecycle reconstruction. When billing or audit asks “what happened during this session,” the StatusNotification trail helps.

Customer app integration. Users see “charging” or “session ended” based on this data.

Without StatusNotification, the CSMS would be blind to most of what’s happening at the charger.

Common implementation issues

A list of things that go wrong.

Missing transitions

The charger doesn’t send StatusNotification on every transition. CSMS misses state changes. Session shows wrong state for periods.

Mitigation: TriggerMessage StatusNotification periodically for verification. Detect missing transitions via gap analysis in your CSMS. A healthy Heartbeat and connection lifecycle (coming soon) also tells you whether a silent connector is offline or simply not transitioning.

Late transitions

StatusNotification fires after a delay (network or processing latency). Dashboard shows stale state.

Mitigation: show timestamp alongside state in dashboard. Accept some lag.

Out-of-order transitions

StatusNotifications arrive out of order (network issue). CSMS interprets the older state as current.

Mitigation: use timestamp, not arrival time, for ordering. Reject states older than what you’ve already processed.

Stuck in transitional state

Charger stuck in Preparing or Finishing for hours. State machine bug.

Mitigation: alert on state durations exceeding expected ranges. Investigate.

Phantom Reserved state

Reservation was cancelled but the charger still shows Reserved. Lost CancelReservation message.

Mitigation: reconcile reservation state on charger reconnect.

Faulted with no real fault

The charger reports Faulted but everything looks fine on inspection. Sensor drift, firmware bug.

Mitigation: alert on Faulted; if persistent, escalate; if false-positive, possibly suppress with care.

State flapping

Connector rapidly oscillates between states (Available ↔ Preparing many times). Bad cellular, contact issue, firmware bug.

Mitigation: detect flap patterns; alert.

What the CSMS should do

A few principles.

Persist every state change. Audit log of state transitions per connector.

Display current state in dashboard. With timestamp of last transition.

Compute durations. “Connector has been in this state for X minutes.” Useful for identifying stuck transitions.

Alert on anomalies. Faulted, long-duration transitional states, frequent flapping.

Cross-reference with sessions. A session shows Charging in your transaction view but the connector shows Available — something’s wrong.

Handle out-of-order events. Use timestamps, not arrival order.

Snapshot reconciliation. Periodically (or on charger reconnect) trigger fresh StatusNotifications to verify state.

What the charger should do

For firmware engineers.

Send StatusNotification on every meaningful transition. Don’t skip transitions because they were brief.

Use accurate timestamps. State changes should be timestamped at the moment of transition.

Distinguish Faulted clearly. Don’t conflate Faulted with Unavailable or Preparing.

Handle reservations correctly. Reserved state should be enforced; transition to Reserved on ReserveNow accepted, back to Available on cancellation or expiry.

Don’t flap on transient conditions. If a connector goes Faulted for 100ms due to a sensor blip, don’t flood the CSMS with state notifications.

Vendor-specific extension. Use vendor extensions sparingly; the standard states cover most cases.

The honest summary

StatusNotification is the lifeblood of OCPP operational visibility. The state machine is well-defined; the implementation quality varies. Good chargers fire StatusNotifications reliably on every meaningful transition. Good CSMSes use them to maintain accurate operational views and drive alerts. Most “why doesn’t the dashboard match reality” issues trace back to this layer — invest carefully and the rest of operations gets much easier.

Quick check

Q1. When does a charger fire StatusNotification?
Q2. What does connectorId 0 report?
Q3. Two StatusNotifications arrive out of order due to a network issue. How should the CSMS decide which state is current?
Q4. How is connector status represented in OCPP 2.0.1?
Q5. A connector is stuck in Preparing for hours. What is the right CSMS response?

Frequently asked questions

How often does StatusNotification fire?

On every connector state change. So once when a user plugs in (Available → Preparing), once when charging begins (Preparing → Charging), once when charging completes (Charging → Finishing), and once when the user unplugs (Finishing → Available). Plus on faults or other state changes. Not on a fixed interval.

What is the connectorId for the whole charger?

connectorId = 0. StatusNotification with connectorId 0 reports the state of the entire charger, not a specific connector. Used for charger-level faults that affect all connectors.

Does OCPP 2.0.1 still use StatusNotification?

Yes, but with more structure. The 2.0.1 version uses the device model — status is reported via OperationalStatus and AvailabilityState variables on the relevant components (EVSE, Connector). The functional equivalent is the same; the structure is cleaner.

What does Reserved status mean?

A connector has an active reservation. Other users (not the reservation holder) cannot start sessions. Reservation lifecycle is managed via ReserveNow / CancelReservation messages.

Found this useful? Share it.