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:
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
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
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 |
|---|---|
| Absolute | Periods are absolute wall-clock times from startSchedule. Use for one-time events or time-of-use tariff windows tied to a specific date/time. |
| Recurring | Periods repeat Daily or Weekly (set via recurrencyKind). Use for permanent overnight schedules or workday/weekend power limits. Requires startSchedule as the reference point. |
| Relative | Periods 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 |
|---|---|---|
| chargingRateUnit | Yes | A (amperes) or W (watts). All period limits in this schedule must use the same unit. |
| chargingSchedulePeriod | Yes | Array of periods. Each period: startPeriod (seconds offset from schedule start), limit (max power/current, can have 0.1 precision), optional numberPhases. |
| duration | No | Total schedule duration in seconds. After this, the last period's limit continues indefinitely until cleared. |
| startSchedule | No | Required for Absolute and Recurring profiles. The UTC date-time from which period offsets are calculated. |
| minChargingRate | No | Minimum 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:
- ChargePointMaxProfile caps everything. No profile can cause the Charge Point to exceed the ChargePointMaxProfile limit, regardless of stackLevel.
- Higher stackLevel wins within the same purpose. If two TxDefaultProfiles are active on the same connector, the one with the higher stackLevel takes effect.
- TxProfile overrides TxDefaultProfile. An active TxProfile always wins over any TxDefaultProfile, regardless of stackLevel values.
- 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
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
connectorIdfor 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.
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.
Build a frame in seconds
Form-driven payload builder — pick fields, get a valid frame, copy to clipboard.
Frequently asked questions
What is the difference between chargingRateUnit A and W?
What is stackLevel and how does conflict resolution work?
What is the difference between TxProfile and TxDefaultProfile?
Can a CSMS set a charging profile before the session starts?
What does GetCompositeSchedule return?
Does OCPP 2.0.1 support smart charging?
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/