A profile is a ceiling
The most consequential misunderstanding in this area: setting a limit of 11 kW does not request 11 kW. It forbids more than 11 kW.
The power actually delivered is the minimum of every constraint in play:
actual power = min(
charging profile limit,
charge point hardware rating,
connector / cable rating,
site grid connection limit,
what the vehicle asks for ← often the binding constraint
)A vehicle at 85% state of charge tapers to a fraction of the connector's capability regardless of any profile. Any product feature, grid commitment or billing assumption built on a profile determining actual draw will be wrong. Verify against MeterValues.
SetChargingProfile
// CSMS -> charge point
[2, "19223220", "SetChargingProfile", {
"connectorId": 1,
"csChargingProfiles": {
"chargingProfileId": 4471,
"transactionId": 770142,
"stackLevel": 2,
"chargingProfilePurpose": "TxProfile",
"chargingProfileKind": "Relative",
"chargingSchedule": {
"duration": 28800,
"chargingRateUnit": "W",
"minChargingRate": 1400,
"chargingSchedulePeriod": [
{ "startPeriod": 0, "limit": 7400, "numberPhases": 3 },
{ "startPeriod": 14400, "limit": 22000, "numberPhases": 3 }
]
}
}
}]
// Charge point -> CSMS
[3, "19223220", { "status": "Accepted" }]Response is Accepted, Rejected or NotSupported. Smart charging support is genuinely uneven across hardware, so NotSupported is a capability flag to cache per charger model rather than an error to retry.
Purpose and stack level
This is the mechanism that makes OCPP smart charging more capable than OCPI ChargingProfiles, which exposes only one profile per session.
chargingProfilePurpose | Scope | Set by |
|---|---|---|
ChargePointMaxProfile | The whole charge point, all connectors | The CPO — site and grid limits |
TxDefaultProfile | Default for any transaction | The CPO — standing policy |
TxProfile | One specific transaction | Per-session control, including from OCPI |
stackLevel resolves conflicts within a purpose: higher wins. A TxProfile at stack level 3 overrides one at level 1.
ChargePointMaxProfile capping the site at 50 kW is not overridden by a TxProfile asking for 60 kW — the effective limit remains 50. This is why an eMSP setting a profile through OCPI may see no change at all: the CPO's site cap is already lower, and the eMSP has no visibility into it.chargingProfileKind
| Kind | startPeriod is relative to |
|---|---|
Absolute | startSchedule, an explicit wall-clock time |
Relative | The start of the transaction |
Recurring | A daily or weekly cycle via recurrencyKind |
Relative is usually what you want for per-session control — it does not depend on the charger's clock being correct, which given clock drift is a meaningful robustness gain.
GetCompositeSchedule: what the charger actually plans
With several profiles stacked, working out the effective limit by inspection is error-prone. GetCompositeSchedule asks the charger to flatten everything and report the result.
// CSMS -> charge point
[2, "19223221", "GetCompositeSchedule", {
"connectorId": 1, "duration": 3600, "chargingRateUnit": "W"
}]
// Charge point -> CSMS
[3, "19223221", {
"status": "Accepted",
"connectorId": 1,
"scheduleStart": "2026-08-11T22:00:00Z",
"chargingSchedule": {
"duration": 3600,
"chargingRateUnit": "W",
"chargingSchedulePeriod": [ { "startPeriod": 0, "limit": 7400 } ]
}
}]This is the diagnostic tool for smart charging. When a profile appears to be ignored, this tells you whether the charger received it, how it stacked it, and what limit is actually in force. Use it during commissioning of every new charger model, not only when something breaks.
ClearChargingProfile
Removes profiles by any combination of ID, connector, purpose and stack level:
[2, "19223222", "ClearChargingProfile", {
"id": 4471
}]
[3, "19223222", { "status": "Accepted" }]Unknown comes back when nothing matched — which is usually fine, since the goal was for the profile not to be there.
Clearing with no filters removes every profile on the charger, including site-level ChargePointMaxProfile caps. On a site with a constrained grid connection that can take the installation over its limit. Always scope the clear.
Production lessons
- Always set
minChargingRate. Without a floor, an aggressive limit can drop a vehicle into a trickle or cause it to abort the session. - Verify against MeterValues. A profile is intent; metering is truth. Alert on sustained divergence to find chargers silently ignoring profiles.
- Use
GetCompositeSchedulewhen commissioning each model. Stack behaviour varies between vendors more than the spec suggests. - Never clear profiles unscoped. You will remove site safety caps.
- Prefer
Relativefor per-session profiles to avoid clock-drift dependence. - Cache
NotSupportedper model and stop attempting smart charging where it will never work. - Keep site caps in
ChargePointMaxProfile, never in per-transaction profiles. A site limit that disappears when a session ends is a dangerous design.
Frequently asked questions
No, it sets a ceiling. Actual power is the minimum of the profile limit, the hardware and cable ratings, the site grid limit and what the vehicle asks for. A vehicle near full charge tapers regardless of any profile.
A conflict resolver within a profile purpose — higher stack levels win. Across different purposes, though, constraints combine rather than override, so a site-level ChargePointMaxProfile cap is not overridden by a higher TxProfile limit.
ChargePointMaxProfile applies to the whole charge point and carries site and grid limits. TxDefaultProfile is the standing default for any transaction. TxProfile applies to one specific transaction and is what per-session control, including from OCPI, uses.
It asks the charger to flatten all stacked profiles and report the limit actually in force. It is the primary diagnostic when a profile appears to be ignored, and it should be used when commissioning every new charger model because stack behaviour varies between vendors.
Because the CPO's site-level ChargePointMaxProfile cap is already lower than the limit requested. Constraints across purposes combine rather than override, and an eMSP setting a profile through OCPI has no visibility into the CPO's site caps.