Skip to main content
engineeringFebruary 25, 2026

The OCPP 2.0.1 Device Model Explained: Components, Variables, and Monitoring

OCPP 2.0.1 device model explained — the component-variable architecture replacing flat config keys. Hierarchy, attribute types, and examples.

At a glance

The OCPP 2.0.1 device model is not just a cleaner schema. It changes how teams discover charger capabilities, manage configuration safely, and normalize mixed fleets during rollout.

CSMS and backend engineersCPO integration leadsTeams planning OCPP 2.0.1 rollout
  • Treat the device model as a rollout dependency, not only a protocol detail.
  • Inventory coverage, vendor-specific components, and read-write rights need validation early.
  • Mixed 1.6 and 2.0.1 fleets require a normalized internal model if you want stable operations.
  • Monitoring and report volume can become operational issues if you test only against ideal payloads.
Y
Yacine El Azrak
Co-founder & CEO
9 min read

What this changes for deployers

If you are implementing OCPP 2.0.1 in production, the device model is one of the first places where "spec support" and "deployment readiness" diverge.

For deployers, the real question is not whether a charger can technically answer GetVariables. It is whether your stack can:

  • discover what the charger actually exposes
  • tell standard components from vendor-specific ones
  • write configuration safely without breaking field behavior
  • monitor the right variables without flooding operations
  • normalize 2.0.1 data into the same operational model as the rest of your fleet

If those pieces are weak, the device model becomes another source of rollout friction instead of the improvement it is supposed to be.

Why OCPP 1.6's configuration model broke down

In OCPP 1.6, charger configuration is a flat key-value store. You read and write configuration using GetConfiguration and ChangeConfiguration with keys like HeartbeatInterval, MeterValuesSampledData, or AuthorizeRemoteTxRequests.

This works fine for simple chargers. But modern charging stations are complex:

  • Multiple EVSEs with different capabilities
  • Multiple connectors per EVSE
  • Network interfaces (cellular, WiFi, Ethernet)
  • Power electronics with independent control
  • Display screens, RFID readers, payment terminals

Representing all of this as flat key-value pairs leads to naming nightmares: ConnectorPhaseRotation.1.1, ChargingScheduleAllowedChargingRateUnit.1. There's no structure, no hierarchy, no way to discover what a charger supports.

OCPP 2.0.1's device model fixes this completely.

The component-variable architecture

The device model is a tree of components, each with variables that describe its state and configuration.

┌──────────────────────────────────────────────────────────────┐
│                     ChargingStation                           │
│                     (Root component)                          │
│                                                              │
│  Variables:                                                  │
│  ├─ Available (bool)                                         │
│  ├─ Model (string)                                           │
│  ├─ VendorName (string)                                      │
│  ├─ FirmwareVersion (string)                                 │
│  └─ Power (decimal, watts)                                   │
│                                                              │
│  ┌─────────────────────────┐  ┌─────────────────────────┐   │
│  │         EVSE 1          │  │         EVSE 2          │   │
│  │                         │  │                         │   │
│  │  Variables:             │  │  Variables:             │   │
│  │  ├─ Available (bool)    │  │  ├─ Available (bool)    │   │
│  │  ├─ Power (decimal)     │  │  ├─ Power (decimal)     │   │
│  │  └─ SupplyPhases (int)  │  │  └─ SupplyPhases (int)  │   │
│  │                         │  │                         │   │
│  │  ┌──────────────────┐   │  │  ┌──────────────────┐   │   │
│  │  │   Connector 1    │   │  │  │   Connector 1    │   │   │
│  │  │                  │   │  │  │                  │   │   │
│  │  │  Variables:      │   │  │  │  Variables:      │   │   │
│  │  │  ├─ Available    │   │  │  │  ├─ Available    │   │   │
│  │  │  ├─ ConnectorType│   │  │  │  ├─ ConnectorType│   │   │
│  │  │  └─ SupplyPhases │   │  │  │  └─ SupplyPhases │   │   │
│  │  └──────────────────┘   │  │  └──────────────────┘   │   │
│  └─────────────────────────┘  └─────────────────────────┘   │
│                                                              │
│  ┌────────────────┐  ┌────────────────┐  ┌───────────────┐  │
│  │ Controller     │  │ TokenReader    │  │ Display       │  │
│  │                │  │                │  │               │  │
│  │ Variables:     │  │ Variables:     │  │ Variables:    │  │
│  │ ├─ Identity    │  │ ├─ Available   │  │ ├─ Available  │  │
│  │ ├─ Interval    │  │ └─ Type       │  │ └─ Language   │  │
│  │ └─ Retries     │  │   (RFID/NFC)  │  │               │  │
│  └────────────────┘  └────────────────┘  └───────────────┘  │
└──────────────────────────────────────────────────────────────┘

Every physical or logical part of the charger is a component. Every property of that component is a variable.

Components in detail

A component is identified by three fields:

  • name — what it is (e.g., "EVSE", "Connector", "Controller")
  • instance — which one, if there are multiples (e.g., "1", "2")
  • evse — which EVSE it belongs to (for EVSE-scoped components)

This gives you a precise address for anything on the charger:

Component: EVSE, instance: 1
  └─ Variable: Available → true

  Component: Connector, instance: 1, evse: {id: 1}
  └─ Variable: ConnectorType → "cType2"

  Component: Controller
  └─ Variable: HeartbeatInterval → 60

Standard components

OCPP 2.0.1 defines a set of standard components that all chargers should support:

| Component | Description | |-----------|------------| | ChargingStation | The station itself | | EVSE | Each charging point | | Connector | Physical connector | | Controller | OCPP communication controller | | SecurityCtrlr | Security settings | | AuthCtrlr | Authorization settings | | TxCtrlr | Transaction settings | | SampledDataCtrlr | Meter value configuration | | MonitoringCtrlr | Monitoring and alerting | | ClockCtrlr | Time synchronization | | DisplayMessageCtrlr | On-screen messages | | LocalAuthListCtrlr | Local authorization list | | SmartChargingCtrlr | Smart charging capabilities | | ReservationCtrlr | Reservation settings |

Vendors can add custom components for hardware-specific features.

Variables and attribute types

Each variable has up to four attribute types, each representing a different aspect:

┌─────────────────────────────────────────────────────┐
│  Variable: "Power" on EVSE 1                        │
│                                                     │
│  ┌──────────────┐  ┌───────────────┐               │
│  │   Actual      │  │   MaxSet      │               │
│  │   (read-only) │  │  (read-write) │               │
│  │               │  │               │               │
│  │  Current      │  │  Maximum      │               │
│  │  power draw:  │  │  allowed:     │               │
│  │  15,400 W     │  │  22,000 W     │               │
│  └──────────────┘  └───────────────┘               │
│                                                     │
│  ┌──────────────┐  ┌───────────────┐               │
│  │   MinSet      │  │   Target      │               │
│  │  (read-write) │  │  (read-write) │               │
│  │               │  │               │               │
│  │  Minimum      │  │  Desired      │               │
│  │  allowed:     │  │  setpoint:    │               │
│  │  6,000 W      │  │  11,000 W     │               │
│  └──────────────┘  └───────────────┘               │
│                                                     │
│  Effective power = MIN(MaxSet, Target) = 11,000 W   │
│  Constrained by MinSet: must be >= 6,000 W          │
│  Actual shows real-time measurement: 15,400 W       │
└─────────────────────────────────────────────────────┘

Actual

The current, real-time value. Read-only. Updated by the charger as conditions change.

Examples:

  • Power.Actual = 15400 (watts currently being drawn)
  • Temperature.Actual = 42 (degrees Celsius)
  • Available.Actual = true (connector is available)

MaxSet

The maximum allowed value. Can be set by the CSMS to impose limits.

Examples:

  • Power.MaxSet = 22000 (don't exceed 22 kW)
  • CurrentImport.MaxSet = 32 (max 32 amps)

MinSet

The minimum allowed value. Used to prevent settings below safe thresholds.

Examples:

  • Power.MinSet = 1380 (minimum charging power: 6A single phase)

Target

The desired setpoint. What you want the value to be.

Examples:

  • Power.Target = 11000 (we want this EVSE to deliver 11 kW)

Reading the device model

OCPP 2.0.1 provides two messages for reading the device model:

GetVariables

Request specific variables by component and variable name:

Request:
  getVariableData: [
    { component: {name: "EVSE", evse: {id: 1}},
      variable: {name: "Power"},
      attributeType: "Actual" },
    { component: {name: "Controller"},
      variable: {name: "HeartbeatInterval"},
      attributeType: "Actual" }
  ]

Response:
  getVariableResult: [
    { attributeValue: "15400",
      attributeStatus: "Accepted" },
    { attributeValue: "60",
      attributeStatus: "Accepted" }
  ]

GetBaseReport

Request a complete dump of the device model:

Request:
  requestId: 1
  reportBase: "FullInventory"

The charger responds with multiple NotifyReport messages
containing ALL components and variables.

FullInventory returns everything. ConfigurationInventory returns only configurable variables. SummaryInventory returns a summary.

Writing to the device model

SetVariables

Change one or more variables:

Request:
  setVariableData: [
    { component: {name: "Controller"},
      variable: {name: "HeartbeatInterval"},
      attributeType: "Target",
      attributeValue: "30" }
  ]

Response:
  setVariableResult: [
    { attributeStatus: "Accepted" }
  ]

Possible responses: Accepted, Rejected, RebootRequired, NotSupportedAttributeType, UnknownComponent, UnknownVariable.

Monitoring

The device model also supports monitoring — the charger can alert the backend when variables change or cross thresholds.

┌─────────────────────────────────────────────────────┐
│  Monitor: Temperature on EVSE 1                     │
│                                                     │
│  Type: UpperThreshold                               │
│  Value: 70 (degrees Celsius)                        │
│  Severity: 2 (critical)                             │
│                                                     │
│  When Temperature.Actual > 70°C:                    │
│    → Charger sends NotifyEvent to CSMS              │
│    → Event includes component, variable, value,     │
│      timestamp, and severity                        │
│                                                     │
│  Monitor types:                                     │
│  ├─ UpperThreshold (value exceeds limit)            │
│  ├─ LowerThreshold (value drops below limit)        │
│  ├─ Delta (value changes by more than X)            │
│  └─ Periodic (report value every N seconds)         │
└─────────────────────────────────────────────────────┘

You set monitors via SetVariableMonitoring and receive alerts via NotifyEvent.

Deployment checklist before you rely on the device model

Before you call a 2.0.1 rollout "ready," validate these points against real hardware:

  1. Inventory completeness Can the charger return a usable FullInventory or ConfigurationInventory without truncation, timeout, or undocumented omissions?
  2. Write permissions Which variables are truly writable, which require reboot, and which are marked writable in theory but rejected in practice?
  3. Vendor extensions Which non-standard components and variables matter for your hardware, and how are they represented in your internal data model?
  4. Report size and performance How large are NotifyReport payloads, and can your backend ingest them without breaking observability or queueing?
  5. State normalization How do you map 2.0.1 component-variable data into the same operational views used for 1.6 chargers?
  6. Monitoring noise Which monitors are essential for operations, and which ones generate event volume without operational value?

If your team has not tested those six areas, you probably understand the device model conceptually but not operationally.

Comparison: OCPP 1.6 vs 2.0.1 configuration

| Aspect | OCPP 1.6 | OCPP 2.0.1 | |--------|----------|------------| | Structure | Flat key-value | Hierarchical component-variable | | Discovery | GetConfiguration (all keys) | GetBaseReport (structured inventory) | | Scope | Station-wide only | Component-scoped (station, EVSE, connector) | | Data types | String only | String, Integer, Decimal, Boolean, DateTime | | Read/write | GetConfiguration / ChangeConfiguration | GetVariables / SetVariables | | Monitoring | None (poll only) | Built-in threshold and delta monitoring | | Real-time values | No (configuration only) | Yes (Actual attribute type) | | Multiple instances | Naming convention (key.1, key.2) | Native EVSE/instance addressing |

How EV Cloud uses the device model

EV Cloud fully leverages the OCPP 2.0.1 device model:

  • Auto-discovery — on first connection, EV Cloud requests a full inventory and builds a live model of the charger's capabilities
  • Configuration management — view and edit all variables from the dashboard, with change tracking
  • Real-time monitoring — automatic monitors on critical variables (temperature, power, availability) with alerting
  • Fleet-wide policies — set configuration templates and apply them across charger groups
  • OCPP 1.6 compatibility — for 1.6 chargers, EV Cloud maps flat configuration keys into the device model structure for a unified interface

Next step for rollout teams

If the device model is part of an active 2.0.1 rollout, continue with:

  1. OCPP 2.0.1: what actually changed for message-level migration impact.
  2. OCPP 1.6 to 2.0.1 migration guide for coexistence strategy.
  3. How to evaluate an OCPP platform if this affects vendor selection, tooling, or rollout architecture.

Frequently asked questions

Short answers for operators evaluating this topic in production.

Continue evaluation

Turn this topic into a buying decision

Use these pages to move from protocol research into shortlist design, migration planning, and commercial evaluation.

From content to rollout

Need help applying this in a live EV charging stack?

EV Cloud helps operators connect chargers, roaming partners, and internal platforms without rewriting their entire backend. Use the guide above for strategy, then use the product pages below for rollout planning.