Meter Values Section — Migration Guide
Use cases J01–J03 (Meter Values). Perspective: CSMS Developer.
Created by tzi.app — your guide to migrating from OCPP 2.0.1 to OCPP 2.1.
1. Summary of Changes
High-Level Overview
| Area | Change Type | Description |
|---|---|---|
| SignedMeterValueType | Breaking | signingMethod and publicKey changed from required to optional; signedMeterData maxLength increased 2500 → 32768 |
| LocationEnumType | New value | Upstream added for grid-side measurements |
| MeasurandEnumType | Major expansion | ~30 new measurands added (Display, EnergyRequest, V2X, cable loss, setpoints, min/max variants) |
| TriggerReasonEnumType | New values | ~12 new trigger reasons (cost/energy/time/SoC limits, tariff, V2X, etc.) |
| TransactionEventRequest | Extended | costDetails, preconditioningStatus, evseSleep, numberOfPhasesUsed, cableMaxCurrent, reservationId, customData added |
| TransactionType | Extended | remoteStartId, operationMode, tariffId, transactionLimit added; new stoppedReason value |
| TransactionEventResponse | Extended | transactionLimit added for cost/energy/time/SoC limits |
| MeterValuesRequest/Response | Extended | customData added to both request and response |
| Configuration Variables | New | Upstream sampled data configuration variables added |
| J02.FR.12 | Clarified | Now explicitly specifies which triggerReason values can be dropped when offline |
| Public Key Format | New | J02.FR.23 adds recommended format for publicKey field |
2. Data Type & Schema Changes
2.1 SignedMeterValueType Breaking
This is the most impactful schema change in this section. Two previously required fields are now optional.
| Field | OCPP 2.0.1 | OCPP 2.1 | Action Required |
|---|---|---|---|
signedMeterData | Required, max 2500 chars | Required, max 32768 chars | Update validation to accept much larger signed data payloads |
signingMethod | Required, max 50 chars | Optional, max 50 chars | Update validation — field may be absent |
encodingMethod | Required, max 50 chars | Required, max 50 chars | No change |
publicKey | Required, max 2500 chars | Optional, max 2500 chars | Update validation — field may be absent |
{
"signedMeterData": "...", // required
"signingMethod": "...", // required
"encodingMethod": "...", // required
"publicKey": "..." // required
}{
"signedMeterData": "...", // required (max 32768)
"signingMethod": "...", // OPTIONAL
"encodingMethod": "...", // required
"publicKey": "..." // OPTIONAL
}New in 2.1 (J02.FR.23): The publicKey field, when present, is RECOMMENDED to follow the format: <marker>:<encoding>:<content-type>:<printed-public-key>
Example: oca:base16:asn1:3056301006072a8648ce3d020106...
2.2 LocationEnumType — New Value
| Value | Version | Description |
|---|---|---|
Body | Both | Body of the Charging Station |
Cable | Both | The charging cable |
EV | Both | The Electric Vehicle |
Inlet | Both | Grid inlet (upstream) |
Outlet | Both | Default. Connector outlet |
Upstream | 2.1 only | Upstream of the Charging Station (grid side). Privacy-sensitive data, may require explicit agreement |
CSMS Action: Update location validation to accept Upstream. Be aware of privacy regulations around upstream meter data.
2.3 MeterValuesRequest / MeterValuesResponse — customData
Both MeterValuesRequest and MeterValuesResponse gain an optional customData field in 2.1.
MeterValuesRequest:
{
"evseId": 1,
"meterValue": [...]
}
MeterValuesResponse:
{}MeterValuesRequest:
{
"evseId": 1,
"meterValue": [...],
+ "customData": { "vendorId": "..." }
}
MeterValuesResponse:
{
+ "customData": { "vendorId": "..." }
}2.4 UnitOfMeasureType
No structural changes. Both versions share the same schema (unit string max 20, multiplier integer, defaults Wh / 0).
2.5 ReadingContextEnumType
No changes. All 8 values remain identical across both versions.
2.6 PhaseEnumType
No changes. All 10 values remain identical across both versions.
3. New Measurands (MeasurandEnumType)
OCPP 2.1 significantly expands the list of supported measurands. All 2.0.1 measurands are retained. The following are new in 2.1.
Energy Measurands (New)
| Measurand | Description | Unit |
|---|---|---|
Energy.Active.Import.CableLoss | Cable loss energy | Wh |
Energy.Active.Import.LocalGeneration.Register | Local generation register | Wh |
Energy.Active.Setpoint.Interval | Setpoint energy during interval | Wh |
Power Measurands (New)
| Measurand | Description | Unit |
|---|---|---|
Power.Active.Setpoint | Active power setpoint | W |
Power.Active.Residual | Residual active power | W |
Power.Import.Offered | Power import offered | W |
Power.Import.Minimum | Minimum power import | W |
Power.Export.Offered | Power export offered | W |
Power.Export.Minimum | Minimum power export | W |
Current Measurands (New)
| Measurand | Description | Unit |
|---|---|---|
Current.Import.Offered | Current import offered | A |
Current.Import.Minimum | Minimum current import | A |
Current.Export.Offered | Current export offered | A |
Current.Export.Minimum | Minimum current export | A |
Voltage Measurands (New)
| Measurand | Description | Unit |
|---|---|---|
Voltage.Minimum | Minimum voltage | V |
Voltage.Maximum | Maximum voltage | V |
Display Measurands New category
| Measurand | Description | Unit |
|---|---|---|
Display.PresentSOC | Present SoC for display | % |
Display.MinimumSOC | Minimum SoC | % |
Display.TargetSOC | Target SoC | % |
Display.MaximumSOC | Maximum SoC | % |
Display.RemainingTimeToMinimumSOC | Remaining time to min SoC | s |
Display.RemainingTimeToTargetSOC | Remaining time to target SoC | s |
Display.RemainingTimeToMaximumSOC | Remaining time to max SoC | s |
Display.ChargingComplete | Charging complete flag | — |
Display.BatteryEnergyCapacity | Battery energy capacity | Wh |
Display.InletHot | Inlet hot indicator | — |
EnergyRequest Measurands New category
| Measurand | Description | Unit |
|---|---|---|
EnergyRequest.Target | Target energy request | Wh |
EnergyRequest.Minimum | Minimum energy request | Wh |
EnergyRequest.Maximum | Maximum energy request | Wh |
EnergyRequest.Minimum.V2X | V2X minimum energy request | Wh |
EnergyRequest.Maximum.V2X | V2X maximum energy request | Wh |
EnergyRequest.Bulk | Bulk energy request | Wh |
CSMS Action: Update measurand validation/enum to accept all new values. The Display.* and EnergyRequest.* categories support V2X and smart charging scenarios.
4. New Trigger Reasons (TriggerReasonEnumType)
The following trigger reasons are new in 2.1:
| Value | Description |
|---|---|
AbnormalCondition | Triggered by an abnormal condition |
CostLimitReached | Transaction cost limit reached |
EnergyLimitReached | Transaction energy limit reached |
LimitSet | A limit was set on the transaction |
OperationModeChanged | EVSE operation mode changed |
RunningCost | Running cost update trigger |
SignedDataReceived | ISO 15118 signed meter data received from EV |
SoCLimitReached | State of Charge limit reached |
TariffChanged | Tariff changed during transaction |
TariffNotAccepted | EV/driver did not accept the tariff |
TimeLimitReached | Transaction time limit reached |
TxResumed | Transaction resumed (e.g., after power loss) |
Trigger reasons retained from 2.0.1: Authorized, CablePluggedIn, ChargingRateChanged, ChargingStateChanged, Deauthorized, EVCommunicationLost, EVConnectTimeout, EVDeparted, EVDetected, MeterValueClock, MeterValuePeriodic, RemoteStart, RemoteStop, ResetCommand, StopAuthorized, Trigger, UnlockCommand.
CSMS Action: Update triggerReason validation/enum. Many new reasons are related to transaction limits and tariff management. These may arrive with or without meterValue data.
5. TransactionEventRequest Changes
5.1 New Top-Level Fields
{
"eventType": "...",
"timestamp": "...",
"triggerReason": "...",
"seqNo": 0,
"transactionInfo": {...},
"meterValue": [...],
"evse": {...},
"idToken": {...},
"offline": false
}{
"eventType": "...",
"timestamp": "...",
"triggerReason": "...",
"seqNo": 0,
"transactionInfo": {...},
"meterValue": [...],
"evse": {...},
"idToken": {...},
"offline": false,
+ "numberOfPhasesUsed": 3,
+ "cableMaxCurrent": 32,
+ "reservationId": 123,
+ "costDetails": {...},
+ "preconditioningStatus": "Ready",
+ "evseSleep": false,
+ "customData": {...}
}| Field | Type | Description |
|---|---|---|
numberOfPhasesUsed | integer (0-3) | Number of phases in use during charging |
cableMaxCurrent | integer | Maximum current the cable supports |
reservationId | integer (≥0) | Associated reservation ID |
costDetails | CostDetailsType | Detailed cost breakdown |
preconditioningStatus | enum | EV battery preconditioning status: Unknown, Ready, NotReady, Preconditioning |
evseSleep | boolean | Whether the EVSE is in sleep mode |
customData | CustomDataType | Vendor-specific extension data |
5.2 TransactionType — New Fields
{
"transactionId": "...",
"chargingState": "...",
"timeSpentCharging": 300,
"stoppedReason": "..."
}{
"transactionId": "...",
"chargingState": "...",
"timeSpentCharging": 300,
"stoppedReason": "...",
+ "remoteStartId": 42,
+ "operationMode": "ChargingOnly",
+ "tariffId": "tariff-abc-123",
+ "transactionLimit": {
+ "maxCost": 50.00,
+ "maxEnergy": 60000,
+ "maxTime": 7200,
+ "maxSoC": 80
+ }
}| Field | Type | Description |
|---|---|---|
remoteStartId | integer | ID of the remote start request that initiated this transaction |
operationMode | enum | EVSE operation mode: Idle, ChargingOnly, CentralSetpoint, ExternalSetpoint, ExternalLimits, CentralFrequency, LocalFrequency, LocalLoadBalancing |
tariffId | string (max 60) | Identifier of the tariff applied to this transaction |
transactionLimit | TransactionLimitType | Cost/energy/time/SoC limits set on the transaction |
5.3 StoppedReasonEnumType — New Value New
| Value | Version | Description |
|---|---|---|
ReqEnergyTransferRejected | 2.1 only | The requested energy transfer mode was rejected |
All existing stoppedReason values remain unchanged.
6. TransactionEventResponse Changes
New Field: transactionLimit Extended
{
"totalCost": 12.50,
"chargingPriority": 0,
"idTokenInfo": {...},
"updatedPersonalMessage": {...}
}{
"totalCost": 12.50,
"chargingPriority": 0,
"idTokenInfo": {...},
"updatedPersonalMessage": {...},
+ "transactionLimit": {
+ "maxCost": 50.00,
+ "maxEnergy": 60000,
+ "maxTime": 7200,
+ "maxSoC": 80
+ },
+ "customData": {...}
}| Field | Type | Description |
|---|---|---|
transactionLimit | TransactionLimitType | CSMS can set cost/energy/time/SoC limits. The CS will stop the transaction when any limit is reached. |
customData | CustomDataType | Vendor-specific extension data |
CSMS Action: The transactionLimit field enables the CSMS to dynamically control transaction boundaries. When a limit is reached, the CS sends a TransactionEventRequest with the corresponding new triggerReason (CostLimitReached, EnergyLimitReached, TimeLimitReached, SoCLimitReached).
7. Use Case Changes (J01–J03)
J01 — Sending Meter Values Not Related to a Transaction
No functional changes to the flow. The core behavior (CS sends MeterValuesRequest, CSMS responds with MeterValuesResponse) remains identical.
| Change | Details |
|---|---|
customData field | Added to both MeterValuesRequest and MeterValuesResponse |
New Upstream location | Meter values may now come with location: "Upstream" |
| New measurands | CS may report new measurand types if configured |
All J01 requirements (J01.FR.02 through J01.FR.22) remain unchanged.
J02 — Sending Transaction Related Meter Values
The flow remains the same (CS sends TransactionEventRequest, CSMS responds with TransactionEventResponse), but the message payloads are expanded.
| Change | Details |
|---|---|
| New TransactionEventRequest fields | costDetails, preconditioningStatus, evseSleep, numberOfPhasesUsed, cableMaxCurrent, reservationId |
| New TransactionType fields | remoteStartId, operationMode, tariffId, transactionLimit |
| New TransactionEventResponse field | transactionLimit for dynamic limit control |
| J02.FR.12 clarification Clarified | 2.1 explicitly states CS MAY drop messages with triggerReason=MeterValueClock or MeterValuePeriodic (2.0.1 was less specific about which Updated messages could be dropped) |
| J02.FR.23 New | Recommended format for publicKey field in SignedMeterValueType |
All other J02 requirements (J02.FR.02 through J02.FR.22) remain unchanged.
J03 — ISO 15118 Charging Loop with Metering Information Exchange
No functional changes. The CSMS handling remains transparent — treat identically to J02. The ISO 15118 metering exchange between EV and CS is unchanged.
J03.FR.04 remains unchanged.
8. Configuration Variable Changes
New Variables in 2.1 New
| Variable | Description |
|---|---|
SampledDataUpstreamMeasurands | Comma-separated list of upstream measurands included in TransactionEventRequest(eventType=Started/Updated) |
SampledDataUpstreamInterval | Interval in seconds for upstream sampled measurands |
AlignedDataUpstreamMeasurands | Comma-separated list of upstream measurands for clock-aligned readings |
AlignedDataUpstreamInterval | Interval in seconds for upstream clock-aligned data |
Changed Variables (2.0.1 → 2.1)
In 2.0.1, upstream configuration was limited to aligned data only: AlignedDataCtrlr.UpstreamMeasurands and AlignedDataCtrlr.UpstreamInterval. In 2.1, upstream configuration is expanded to cover both sampled and aligned data with the four variables listed above.
Warning: Upstream measurands may contain privacy-sensitive data. The CSMS should be aware of regulatory requirements and may need explicit agreements before collecting upstream meter data.
Unchanged Variables
All other configuration variables remain the same across both versions:
SampledDataCtrlr.TxStartedMeasurandsSampledDataCtrlr.TxUpdatedMeasurandsSampledDataCtrlr.TxUpdatedIntervalSampledDataCtrlr.TxEndedMeasurandsSampledDataCtrlr.TxEndedIntervalAlignedDataCtrlr.MeasurandsAlignedDataCtrlr.IntervalAlignedDataCtrlr.TxEndedMeasurandsAlignedDataCtrlr.TxEndedIntervalAlignedDataSendDuringIdleAlignedDataSignReadingsSampledDataSignReadingsSampledDataRegisterValuesWithoutPhases
9. Migration Checklist
Schema & Validation Updates
Accept signingMethod and publicKey as optional (no longer required)
Accept signedMeterData up to 32768 chars (was 2500)
Accept new Upstream value
Accept all ~30 new measurands (Display.*, EnergyRequest.*, cable loss, setpoints, min/max variants)
Accept ~12 new trigger reasons (CostLimitReached, EnergyLimitReached, SoCLimitReached, TimeLimitReached, TariffChanged, etc.)
Accept new ReqEnergyTransferRejected value
Accept optional customData field
Optionally parse/validate the new recommended oca:base16:asn1:... format
TransactionEventRequest Handling
Accept and store new optional fields: costDetails, preconditioningStatus, evseSleep, numberOfPhasesUsed, cableMaxCurrent, reservationId
Accept and store new TransactionType fields: remoteStartId, operationMode, tariffId, transactionLimit
TransactionEventResponse Construction
Support sending transactionLimit in response (with maxCost, maxEnergy, maxTime, maxSoC)
Support sending customData in response
Configuration
Support configuring new upstream measurement variables (SampledDataUpstreamMeasurands, SampledDataUpstreamInterval, AlignedDataUpstreamMeasurands, AlignedDataUpstreamInterval)
Implement privacy controls for upstream meter data
Business Logic
Handle new trigger reasons that indicate transaction limits were reached
Use transactionLimit in response to dynamically control transaction boundaries
Process costDetails from TransactionEventRequest if cost tracking is implemented
Handle operationMode for V2X / smart charging scenarios