Advanced Guide · OCPP · 11 min read

OCPP Smart Charging: SetChargingProfile Explained

How OCPP 1.6 smart charging works — the three profile purpose types, Absolute/Recurring/Relative kind, ChargingSchedule periods, stackLevel conflict resolution, and real-world examples for fleet and grid management.

Published · Reviewed against official OCA specification
RC
By Rodolfo Carrillo
Quick answer

A charging profile is a time-scheduled power or current limit the CSMS pushes to a Charge Point via SetChargingProfile. It defines who it applies to (chargingProfilePurpose: ChargePointMaxProfile, TxDefaultProfile, or TxProfile), when (chargingProfileKind: Absolute, Recurring, or Relative), and how much power (a chargingSchedule with time-sliced period limits in A or W). Higher stackLevel values take priority.

What is smart charging?

Smart charging is the mechanism by which a CSMS controls the power output of Charge Points in real time. Instead of letting every EV draw its maximum rate simultaneously — which can overload a building's electrical infrastructure or incur demand charges — the CSMS dynamically adjusts each charger's limit based on grid capacity, tariffs, and fleet priorities.

In OCPP 1.6, smart charging is implemented through charging profiles — structured objects that define a power/current schedule. The Charge Point is responsible for enforcing the schedule; the CSMS is responsible for designing and pushing it (Open Charge Alliance, 2015, §4.13).

Profile purpose types

The chargingProfilePurpose field defines scope — what the profile applies to:

MAX

ChargePointMaxProfile

The absolute maximum power the entire Charge Point is allowed to draw from the grid — the site-level cap. Applies to connectorId 0. This profile limits all connectors combined and cannot be overridden by lower-level profiles. Set it to protect building transformers and demand tariff thresholds.

stackLevel 0+ · connectorId 0

DEF

TxDefaultProfile

A session template applied automatically to every new transaction on a connector. If connectorId 0, it applies to all connectors. Useful for recurring schedules like "limit to 6A overnight, full power 6am–10pm". Persists across sessions until explicitly cleared.

stackLevel 0+ · connectorId 0 or specific

TX

TxProfile

Tied to a specific active transaction via transactionId. Takes priority over TxDefaultProfile. Automatically removed when the transaction ends. Use for per-session dynamic limits — e.g. a driver's purchased energy tier, or a demand-response event during a specific session.

stackLevel 0+ · specific connectorId · requires transactionId

Profile kind (timing)

Kind Schedule reference & use case
AbsolutePeriods are absolute wall-clock times from startSchedule. Use for one-time events or time-of-use tariff windows tied to a specific date/time.
RecurringPeriods repeat Daily or Weekly (set via recurrencyKind). Use for permanent overnight schedules or workday/weekend power limits. Requires startSchedule as the reference point.
RelativePeriods are relative to the start of the transaction (seconds offset). Use for session-scoped profiles: "limit to 3.7 kW for the first 60 min, then full power." No startSchedule needed.

ChargingSchedule structure

The chargingSchedule object defines the actual power limits over time:

Field Required Description
chargingRateUnitYesA (amperes) or W (watts). All period limits in this schedule must use the same unit.
chargingSchedulePeriodYesArray of periods. Each period: startPeriod (seconds offset from schedule start), limit (max power/current, can have 0.1 precision), optional numberPhases.
durationNoTotal schedule duration in seconds. After this, the last period's limit continues indefinitely until cleared.
startScheduleNoRequired for Absolute and Recurring profiles. The UTC date-time from which period offsets are calculated.
minChargingRateNoMinimum charging rate below which the Charge Point should not go (some EVs disconnect if power drops too low).

stackLevel & conflict resolution

When multiple profiles are active on the same connector, the Charge Point must compute the effective limit by combining them according to these rules:

  1. ChargePointMaxProfile caps everything. No profile can cause the Charge Point to exceed the ChargePointMaxProfile limit, regardless of stackLevel.
  2. Higher stackLevel wins within the same purpose. If two TxDefaultProfiles are active on the same connector, the one with the higher stackLevel takes effect.
  3. TxProfile overrides TxDefaultProfile. An active TxProfile always wins over any TxDefaultProfile, regardless of stackLevel values.
  4. Same purpose + same stackLevel + same connector → last one wins. The newer profile replaces the older one.

The Charge Point configuration key ChargeProfileMaxStackLevel sets the maximum allowed stackLevel. The CSMS must query this value before assigning profiles to avoid rejection. Similarly, ChargingScheduleMaxPeriods limits how many periods a schedule can have.

SetChargingProfile

Example: Recurring overnight limit (16A, 22:00–06:00)
[ 2, "scp-001", "SetChargingProfile", "connectorId": 0, // all connectors "csChargingProfiles": "chargingProfileId": 5, "stackLevel": 0, "chargingProfilePurpose": "TxDefaultProfile", "chargingProfileKind": "Recurring", "recurrencyKind": "Daily", "chargingSchedule": "chargingRateUnit": "A", "startSchedule": "2025-05-12T22:00:00Z", "duration": 86400, "chargingSchedulePeriod": [ "startPeriod": 0, "limit": 16 , // 22:00–06:00 → 16A "startPeriod": 28800, "limit": 32 , // 06:00–16:00 → 32A (full) "startPeriod": 57600, "limit": 16 // 16:00–22:00 → 16A (peak) ] ]

Clear & GetCompositeSchedule

ClearChargingProfile removes profiles by chargingProfileId, connector, purpose, or stackLevel — any combination. Send with all fields null to clear everything on a connector.

GetCompositeSchedule asks the Charge Point to merge all active profiles for a connector and return the resulting effective schedule over a requested duration. Use it to verify the Charge Point's computed schedule matches the CSMS's intent before an important event (e.g. a demand-response window).

Real-world examples

🏭 Site-level grid protection

A warehouse with a 100A main breaker has 10 chargers. Set a ChargePointMaxProfile with limit 8A on all units (connectorId 0). Even if the TxDefaultProfile allows 32A per session, the combined draw stays within the breaker limit.

ChargePointMaxProfile · connectorId 0 · stackLevel 1

🌙 Overnight off-peak charging

A residential complex wants to shift load to off-peak hours. Set a Daily Recurring TxDefaultProfile: 6A from 17:00–22:00 (peak), then 32A from 22:00–06:00 (off-peak). EVs plugged in at 6pm charge slowly until midnight, then full speed.

TxDefaultProfile · Recurring Daily · connectorId 0

💰 Session-level energy tier

A CPO sells "Standard" (7.4 kW) and "Fast" (22 kW) session tiers. When a driver starts via the app, the backend sends RemoteStartTransaction with an embedded TxProfile that sets the limit to the purchased tier. The profile is removed when the session ends.

TxProfile · Relative · embedded in RemoteStartTransaction

⚡ Demand-response event

Grid operator signals a demand-response reduction from 14:00–16:00. CSMS pushes a ChargePointMaxProfile at stackLevel 2 with limit 6A, valid from the event start time (Absolute). After the event, ClearChargingProfile removes the override and normal schedules resume.

ChargePointMaxProfile · Absolute · high stackLevel

OCPP 2.0.1 notes

The smart charging model in OCPP 2.0.1 is substantially the same as 1.6, with these additions:

  • evseId replaces connectorId in SetChargingProfile, with a nested connectorId for targeting individual connectors within an EVSE.
  • ISO 15118 Plug & Charge: profiles can be triggered by the vehicle's contract certificate, enabling fully automated session pricing without driver interaction.
  • V2G (vehicle-to-grid): discharge schedules allow negative limits for bidirectional charging — a limit of −7400 W means the vehicle exports 7.4 kW back to the grid.
  • GetChargingProfiles: new message that lets the CSMS read all active profiles currently installed on the Charge Point, without asking it to compute a composite schedule.

Common errors

Mixing A and W within the same schedule

All chargingSchedulePeriod limits must use the same unit as chargingRateUnit. If chargingRateUnit is "A", all limits are in amperes. Mixing units in the same schedule is invalid.

Using TxProfile without a transactionId

TxProfile requires a transactionId to link it to an active session. Without it, the profile has no scope and the Charge Point may reject it or apply it incorrectly.

stackLevel exceeding ChargeProfileMaxStackLevel

The Charge Point rejects profiles with a stackLevel above its configured maximum. Query ChargeProfileMaxStackLevel before building profiles — do not hardcode high stack levels.

Absolute schedule with startSchedule in the past

If startSchedule is before the current time and the schedule has a fixed duration, the schedule may already be fully expired when it arrives. Use Recurring for permanent schedules, or compute startSchedule to be current or future.

Not clearing stale profiles after session end

TxProfiles are cleared automatically on StopTransaction. TxDefaultProfiles and ChargePointMaxProfiles are not — they persist. Build a cleanup process to remove profiles that are no longer needed, or they will silently limit all future sessions.

RC

Rodolfo Carrillo

OCPP integration engineer and creator of OCPP Tools. All articles are verified against the official OCA specification and tested using the on-site tools.

Tool

Build a frame in seconds

Form-driven payload builder — pick fields, get a valid frame, copy to clipboard.

Open Builder →

Frequently asked questions

What is the difference between chargingRateUnit A and W?
A (amperes) expresses the charging limit as a current per phase — the Charge Point's physical current limit. W (watts) expresses it as a total power limit. Use A when the hardware limit is current-based (most AC chargers); use W when you need power-based limits across varying voltages (useful for energy management systems). Both can be multiplied with numberPhases for multi-phase units.
What is stackLevel and how does conflict resolution work?
stackLevel is an integer that sets the priority of a charging profile. Higher numbers win. Profiles with the same purpose and stackLevel on the same connector replace each other — the newer one takes effect. For example, a TxProfile at stackLevel 1 overrides a TxDefaultProfile at stackLevel 0, but a ChargePointMaxProfile at stackLevel 2 caps both.
What is the difference between TxProfile and TxDefaultProfile?
TxDefaultProfile is a session template — it applies to every new transaction unless overridden. TxProfile is tied to a specific active transaction (identified by transactionId). TxProfile takes priority over TxDefaultProfile when both are present. TxProfile is removed when the transaction ends; TxDefaultProfile persists.
Can a CSMS set a charging profile before the session starts?
Yes, using a TxDefaultProfile applied to a specific connector. When the next session starts on that connector, the profile takes effect automatically. Alternatively, the CSMS can embed a TxProfile directly in RemoteStartTransaction.
What does GetCompositeSchedule return?
GetCompositeSchedule asks the Charge Point to compute and return the combined effect of all active charging profiles for a given connector over a specified duration. The result is a single merged schedule showing the effective limit at each time period — accounting for stackLevel priorities and profile overlaps.
Does OCPP 2.0.1 support smart charging?
Yes. OCPP 2.0.1 uses the same charging profile model (purpose, kind, stackLevel, schedule) with minor payload changes. Key additions: ISO 15118 Plug & Charge profile coordination, SetChargingProfile now targets an evseId instead of connectorId, and smart charging profiles can carry V2G (vehicle-to-grid) discharge limits.

Sources & further reading

  • · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, §4.13–§4.15 — Smart Charging. https://openchargealliance.org/my-oca/ocpp/
  • · Open Charge Alliance. (2015). Open Charge Point Protocol 1.6, Edition 2, Appendix 1 — ChargingScheduleMaxPeriods, ChargeProfileMaxStackLevel. https://openchargealliance.org/my-oca/ocpp/
  • · Open Charge Alliance. (2020). Open Charge Point Protocol 2.0.1, §3.14 — Smart Charging. https://openchargealliance.org/my-oca/ocpp/
Last technical review: May 12, 2025

Continue learning