OCPP 2.1 Edition 2 Section J

Meter Values - CSMS Developer Guide

Based on OCPP 2.1 Edition 2 Specification (Part 2), Section J (Meter Values). This guide covers all meter value flows (J01–J03), including non-transaction meter values, transaction-related meter values, and ISO 15118 signed metering from the CSMS perspective using OCPP-J (JSON over WebSocket).

9 Sections
3 Use Cases
J01 – J03

1. Overview

Introduction

The Meter Values functional block enables Charging Stations to send periodic and/or clock-aligned meter readings to the CSMS. There are two categories of meter value delivery, each using a different transport message.

Key Concepts

Non-Transaction Meter Values

Clock-aligned readings sent via MeterValuesRequest when no active transaction exists on the EVSE, or for idle readings.

Transaction Meter Values

Sent via TransactionEventRequest with eventType = Updated during an active transaction.

ISO 15118 Signed Metering

Fiscally signed meter data from ISO 15118 charging loops, delivered as standard TransactionEventRequest messages with signed meter value data.

CSMS as Receiver

Both messages flow from Charging Station → CSMS. The CSMS is always the receiver and responder.

Message Categories

Category Transport Message When Used
Non-transaction meter values MeterValuesRequest No active transaction on the EVSE, or clock-aligned idle readings
Transaction-related meter values TransactionEventRequest During an active transaction (eventType = Updated)

Critical Rules

Important: Transaction-related MeterValues are never transmitted in MeterValuesRequest. They are always sent via TransactionEventRequest.

Direction: Both messages flow from Charging Station → CSMS. The CSMS must always respond promptly. Failure to respond may cause the Charging Station to retry, potentially causing duplicate messages.

2. J01 — Receiving Non-Transaction Meter Values

CS-Initiated
Use Case ID J01
Direction CS → CSMS (CS initiates)
Trigger Clock-aligned interval when EVSE is not in a transaction
OCPP Messages MeterValuesRequest / MeterValuesResponse

Flow Diagram

Sequence Diagram (CSMS perspective)
Charging Station                           CSMS
     |                                       |
     |  MeterValuesRequest(evseId, meterValue)|
     |-------------------------------------->|
     |                                       |  <- Process & store meter data
     |             MeterValuesResponse()     |
     |<--------------------------------------|
     |                                       |

Trigger Conditions

The Charging Station sends MeterValuesRequest when:

  • AlignedDataCtrlr.Interval > 0 AND the EVSE is not involved in a transaction
  • The CSMS has configured the station to periodically send clock-aligned meter values
  • AlignedDataSendDuringIdle controls whether these are only sent when no transactions are active

Incoming Request: MeterValuesRequest

OCPP Action: MeterValues · Direction: Charging Station → CSMS

MeterValuesRequest Schema
{
  "type": "object",
  "required": ["evseId", "meterValue"],
  "properties": {
    "evseId": {
      "type": "integer",
      "minimum": 0,
      "description": "EVSE identifier. 0 = main power meter of the Charging Station."
    },
    "meterValue": {
      "type": "array",
      "items": { "$ref": "#/definitions/MeterValueType" },
      "minItems": 1,
      "description": "One or more MeterValue elements, each with a timestamp and sampled values."
    },
    "customData": { "$ref": "#/definitions/CustomDataType" }
  }
}
Field Type Required Description
evseId integer (>= 0) Yes Identifies the EVSE. 0 means the main power meter (entire Charging Station).
meterValue MeterValueType[] Yes Array of meter value snapshots. Minimum 1 element.
customData CustomDataType No Vendor-specific extension data.

Response: MeterValuesResponse

Requirement J01.FR.18: The CSMS MUST always respond with MeterValuesResponse. Failing to respond may cause the Charging Station to retry the same message.

MeterValuesResponse Schema
{
  "type": "object",
  "properties": {
    "customData": { "$ref": "#/definitions/CustomDataType" }
  }
}

The response body is empty (no required fields). It is purely an acknowledgement.

Minimal Response
{}
With Custom Data
{
  "customData": {
    "vendorId": "com.example.vendor"
  }
}

CSMS Processing Logic

When receiving a MeterValuesRequest, implement the following:

  1. Validate the request against the JSON schema — evseId must be >= 0, meterValue array must have >= 1 element, each MeterValue must have a timestamp and >= 1 SampledValue
  2. Identify the Charging Station and EVSE — look up the station by WebSocket connection/identity. If evseId == 0: data is from the main power meter (grid connection). If evseId > 0: data is from a specific EVSE
  3. Process each MeterValue — extract the timestamp (ISO 8601), then for each SampledValue: read the value, determine the measurand (default: Energy.Active.Import.Register), context (default: Sample.Periodic), location (default: Outlet), and unit (default: Wh)
  4. Apply the multiplieractual_value = value × 10^multiplier (default multiplier: 0). If signedMeterValue is present, store the signed data for auditability
  5. Store the processed meter data in database
  6. Respond with MeterValuesResponse (empty body: {})

Key Requirements (CSMS Perspective)

Req ID Rule
J01.FR.02 The evseId identifies which EVSE the samples were taken from.
J01.FR.03 When evseId is 0, the data is associated with the entire Charging Station.
J01.FR.04 When evseId is 0 and measurand is energy-related, the sample comes from the main energy meter.
J01.FR.05 Each MeterValue element SHALL contain a timestamp.
J01.FR.06 Each MeterValue SHALL contain one or more SampledValue elements.
J01.FR.14 When AlignedDataCtrlr.Interval > 0 and the EVSE is not in a transaction, the CS sends MeterValuesRequest for measurands in AlignedDataCtrlr.Measurands for all evseIds, locations, and phases.
J01.FR.15 The CS MAY use multiple MeterValuesRequest messages if data is too large for one message.
J01.FR.17 The timestamp of a MeterValue applies to all its SampledValues.
J01.FR.18 CSMS SHALL respond with MeterValuesResponse. Failure to respond may cause retries.

Multiple Locations/Phases Handling

A Charging Station capable of measuring multiple locations/phases will send multiple MeterValuesRequest messages. For example, a station measuring Current.Import on Inlet (3 phases per EVSE on each of 2 EVSEs) with AlignedDataCtrlr.Interval = 900 seconds sends:

  • MeterValuesRequest with evseId=0, 3 SampledValue elements (one per phase, location = Inlet)
  • MeterValuesRequest with evseId=1, 3 SampledValue elements (one per phase, location = Outlet)
  • MeterValuesRequest with evseId=2, 3 SampledValue elements (one per phase, location = Outlet)

Note: When SampledDataRegisterValuesWithoutPhases is true, meter values of measurand Energy.Active.Import.Register will only report the total energy over all phases without reporting individual phase values.

3. J02 — Receiving Transaction-Related Meter Values

CS-Initiated
Use Case ID J02
Direction CS → CSMS (CS initiates)
Trigger Periodic interval or clock-aligned interval during active transaction
OCPP Messages TransactionEventRequest / TransactionEventResponse

Flow Diagram

Sequence Diagram (CSMS perspective)
Charging Station                                                    CSMS
     |                                                                |
     |  TransactionEventRequest(eventType=Updated, transactionId,     |
     |                          meterValue)                           |
     |-------------------------------------------------------------->|
     |                                                                |  <- Process meter data
     |                                                                |     + link to transaction
     |                          TransactionEventResponse()            |
     |<--------------------------------------------------------------|
     |                                                                |

Trigger Conditions

The Charging Station sends TransactionEventRequest with meter values when:

  • SampledDataTxUpdatedInterval > 0 and a transaction is active → triggerReason = MeterValuePeriodic
  • Clock-aligned data during a transaction → triggerReason = MeterValueClock (context = Sample.Clock)
  • Transaction start → eventType = Started with start meter values
  • Transaction end → eventType = Ended with end meter values

Incoming Request: TransactionEventRequest

OCPP Action: TransactionEvent · Direction: Charging Station → CSMS

TransactionEventRequest Schema (Top-Level)
{
  "type": "object",
  "required": ["eventType", "timestamp", "triggerReason", "seqNo", "transactionInfo"],
  "properties": {
    "eventType": {
      "type": "string",
      "enum": ["Started", "Updated", "Ended"]
    },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    },
    "triggerReason": {
      "type": "string",
      "enum": [
        "AbnormalCondition", "Authorized", "CablePluggedIn",
        "ChargingRateChanged", "ChargingStateChanged",
        "CostLimitReached", "Deauthorized", "EnergyLimitReached",
        "EVCommunicationLost", "EVConnectTimeout", "EVDeparted",
        "EVDetected", "LimitSet", "MeterValueClock",
        "MeterValuePeriodic", "OperationModeChanged", "RemoteStart",
        "RemoteStop", "ResetCommand", "RunningCost",
        "SignedDataReceived", "SoCLimitReached", "StopAuthorized",
        "TariffChanged", "TariffNotAccepted", "TimeLimitReached",
        "Trigger", "TxResumed", "UnlockCommand"
      ]
    },
    "seqNo": {
      "type": "integer",
      "minimum": 0,
      "description": "Incremental sequence number for ordering transaction events."
    },
    "transactionInfo": {
      "$ref": "#/definitions/TransactionType",
      "description": "Contains transactionId and transaction state."
    },
    "meterValue": {
      "type": "array",
      "items": { "$ref": "#/definitions/MeterValueType" },
      "minItems": 1,
      "description": "Optional. Present when meter data is being reported."
    },
    "evse": { "$ref": "#/definitions/EVSEType" },
    "idToken": { "$ref": "#/definitions/IdTokenType" },
    "offline": { "type": "boolean", "default": false },
    "numberOfPhasesUsed": { "type": "integer", "minimum": 0, "maximum": 3 },
    "cableMaxCurrent": { "type": "integer" },
    "reservationId": { "type": "integer", "minimum": 0 },
    "costDetails": { "$ref": "#/definitions/CostDetailsType" },
    "preconditioningStatus": {
      "type": "string",
      "enum": ["Unknown", "Ready", "NotReady", "Preconditioning"]
    },
    "evseSleep": { "type": "boolean" },
    "customData": { "$ref": "#/definitions/CustomDataType" }
  }
}
TransactionType Schema
{
  "type": "object",
  "required": ["transactionId"],
  "properties": {
    "transactionId": { "type": "string", "maxLength": 36 },
    "chargingState": {
      "type": "string",
      "enum": ["EVConnected", "Charging", "SuspendedEV", "SuspendedEVSE", "Idle"]
    },
    "timeSpentCharging": { "type": "integer" },
    "stoppedReason": {
      "type": "string",
      "enum": [
        "DeAuthorized", "EmergencyStop", "EnergyLimitReached",
        "EVDisconnected", "GroundFault", "ImmediateReset", "MasterPass",
        "Local", "LocalOutOfCredit", "Other", "OvercurrentFault",
        "PowerLoss", "PowerQuality", "Reboot", "Remote",
        "SOCLimitReached", "StoppedByEV", "TimeLimitReached",
        "Timeout", "ReqEnergyTransferRejected"
      ]
    },
    "remoteStartId": { "type": "integer" },
    "operationMode": {
      "type": "string",
      "enum": [
        "Idle", "ChargingOnly", "CentralSetpoint", "ExternalSetpoint",
        "ExternalLimits", "CentralFrequency", "LocalFrequency",
        "LocalLoadBalancing"
      ]
    },
    "tariffId": { "type": "string", "maxLength": 60 },
    "transactionLimit": { "$ref": "#/definitions/TransactionLimitType" }
  }
}

Response: TransactionEventResponse

Requirement J02.FR.19: The CSMS SHALL respond with TransactionEventResponse. Failure to respond may cause retries.

TransactionEventResponse Schema
{
  "type": "object",
  "properties": {
    "totalCost": {
      "type": "number",
      "description": "Running cost (when eventType=Updated) or final cost (when eventType=Ended)."
    },
    "chargingPriority": {
      "type": "integer",
      "description": "Temporary priority override. Range: -9 to 9. Default: 0."
    },
    "idTokenInfo": {
      "$ref": "#/definitions/IdTokenInfoType",
      "description": "Updated authorization status for the token."
    },
    "transactionLimit": {
      "$ref": "#/definitions/TransactionLimitType",
      "description": "Cost/energy/time/SoC limits for the transaction."
    },
    "updatedPersonalMessage": {
      "$ref": "#/definitions/MessageContentType",
      "description": "Message to display to the user on the Charging Station."
    },
    "customData": { "$ref": "#/definitions/CustomDataType" }
  }
}

Note: All fields are optional. A minimal acknowledgement response is an empty JSON object: {}

CSMS Processing Logic

  1. Validate the requesteventType, timestamp, triggerReason, seqNo, and transactionInfo are required
  2. Identify the transaction — look up by transactionInfo.transactionId. If Started: create new record. If Updated: update existing. If Ended: finalize
  3. Check seqNo for ordering — detect missing messages or out-of-order delivery. CS may drop intermediate messages when offline (J02.FR.12/13)
  4. Process meter values (if present) — for each MeterValue, extract timestamp, then for each SampledValue parse value, measurand, context, location, phase, unit, multiplier. Apply multiplier: actual_value = value × 10^multiplier. Link meter data to the transaction
  5. Handle triggerReasonMeterValuePeriodic: periodic sampled data, MeterValueClock: clock-aligned data, SignedDataReceived: ISO 15118 signed meter data
  6. Validate meter data integrity — register values (*.Register) MUST be monotonically increasing (J02.FR.16). Flag decreasing values as anomaly. Meter values SHALL be related to the EVSE of the transaction (J02.FR.22)
  7. Build the response — optionally include totalCost (running or final), idTokenInfo, transactionLimit, or updatedPersonalMessage

Meter Value Trigger Reasons

triggerReason Description Expected meterValue
MeterValuePeriodic Periodic sampled data (every SampledDataTxUpdatedInterval seconds) Yes — sampled measurands from SampledDataCtrlr.TxUpdatedMeasurands
MeterValueClock Clock-aligned data during transaction Yes — measurands from AlignedDataCtrlr.Measurands with context Sample.Clock
SignedDataReceived ISO 15118 signed meter data received from EV Yes — with signedMeterValue field populated

Key Requirements (CSMS Perspective)

Req ID Rule
J02.FR.02 Each MeterValue element SHALL contain one or more SampledValue elements.
J02.FR.10 For eventType=Started/Updated with multiple meterValues: all timestamps must be within the current sampling interval. Only eventType=Ended can have values spanning multiple intervals.
J02.FR.11 When SampledDataTxUpdatedInterval > 0: CS sends TransactionEventRequest(eventType=Updated) with triggerReason=MeterValuePeriodic at every interval.
J02.FR.12 When offline and low on memory, CS MAY drop TransactionEventRequest(eventType=Updated) messages with triggerReason=MeterValueClock or MeterValuePeriodic.
J02.FR.13 When dropping messages, CS drops intermediate ones first (2nd, 4th, 6th, etc.), not from start or end.
J02.FR.14 CS MAY use multiple TransactionEventRequest messages with the same timestamp when data is too large for one message.
J02.FR.16 All "Register" values for a single transaction MUST be monotonically increasing. Exception: meter replacement.
J02.FR.17 Register values SHOULD be reported exactly as read from hardware and SHOULD NOT be re-based to zero.
J02.FR.18 Timestamp of a MeterValue applies to all its SampledValues.
J02.FR.19 CSMS SHALL respond with TransactionEventResponse. Failure may cause retries.
J02.FR.20 For eventType=Ended, CS MAY remove intermediate samples if data is too large. Removal should not affect billing.
J02.FR.22 Meter values in TransactionEventRequest SHALL be related to the EVSE of the transaction.

Offline Behavior

When the Charging Station is offline:

  • It MUST queue transaction-related meter values and send them when back online
  • It MAY drop intermediate Updated events when low on memory (J02.FR.12)
  • Dropped messages follow a pattern: intermediate ones (2nd, 4th, 6th) are removed first (J02.FR.13)

CSMS Detection: Use seqNo to detect gaps and the offline flag to identify queued messages that were sent while the station was disconnected.

4. J03 — ISO 15118 Charging Loop with Metering Information Exchange

CS-Initiated
Use Case ID J03
Direction CS → CSMS (CS initiates)
Trigger ISO 15118 charging loop with fiscal metering data exchange
OCPP Messages TransactionEventRequest / TransactionEventResponse (same as J02)

Flow Diagram

Sequence Diagram (Full ISO 15118 metering exchange)
EV                   Charging Station                                   CSMS
 |                        |                                               |
 |  [ISO 15118]           |                                               |
 |  ChargingStatusReq()   |  (AC Charging)                                |
 |---------------------->|                                               |
 |                        |                                               |
 |  ChargingStatusRes(    |                                               |
 |    MeterInfoRecord,    |                                               |
 |    ReceiptRequired:    |                                               |
 |    True)               |                                               |
 |<-----------------------|                                               |
 |                        |                                               |
 |  MeteringReceiptReq(   |                                               |
 |    Signature)          |                                               |
 |---------------------->|                                               |
 |                        |                                               |
 |  MeteringReceiptRes()  |                                               |
 |<-----------------------|                                               |
 |                        |                                               |
 |                        |  [OCPP]                                       |
 |                        |  TransactionEventRequest(                      |
 |                        |    eventType=Updated,                          |
 |                        |    transactionID, timestamp,                   |
 |                        |    chargingState=Charging,                     |
 |                        |    Signed metervalues)                         |
 |                        |---------------------------------------------->|
 |                        |                                               |
 |                        |                  TransactionEventResponse()   |
 |                        |<----------------------------------------------|
 |                        |                                               |

CSMS Role in J03

From the CSMS perspective, J03 is transparent — the CSMS handles this exactly like J02. The ISO 15118 metering exchange happens between the EV and the Charging Station. What reaches the CSMS is a standard TransactionEventRequest with:

  • eventType = Updated
  • triggerReason = SignedDataReceived (or MeterValuePeriodic)
  • meterValue array containing signedMeterValue data from the fiscal meter

Key Requirement

Req ID Rule
J03.FR.04 The Charging Station SHOULD NOT pass the raw ISO 15118 MeteringReceiptReq meter value in the TransactionEventRequest. Instead, it sends transaction-related meter values as per J02 flow. However, the implementation may ensure every fiscal meter value sent to CSMS was first acknowledged by the EV via MeteringReceiptReq.

CSMS Processing

Handle identically to J02 TransactionEventRequest. The presence of signedMeterValue in the SampledValue indicates ISO 15118 signed metering data. The CSMS should:

  1. Store the signedMeterData (Base64 encoded) for regulatory compliance
  2. Note the encodingMethod (e.g., "OCMF", "EDL") for later decoding
  3. Optionally verify the signature using the publicKey if provided
  4. Store the signingMethod if present

5. Data Types & JSON Schemas Reference

Reference

MeterValueType

A collection of sampled values taken at the same point in time.

MeterValueType Schema
{
  "type": "object",
  "required": ["timestamp", "sampledValue"],
  "properties": {
    "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp. Applies to ALL sampledValues in this MeterValue."
    },
    "sampledValue": {
      "type": "array",
      "items": { "$ref": "#/definitions/SampledValueType" },
      "minItems": 1,
      "description": "One or more individual measurements."
    }
  }
}

SampledValueType

A single measured value with metadata.

SampledValueType Schema
{
  "type": "object",
  "required": ["value"],
  "properties": {
    "value":            { "type": "number",  "description": "The measured value." },
    "measurand":        { "$ref": "#/definitions/MeasurandEnumType" },
    "context":          { "$ref": "#/definitions/ReadingContextEnumType" },
    "phase":            { "$ref": "#/definitions/PhaseEnumType" },
    "location":         { "$ref": "#/definitions/LocationEnumType" },
    "signedMeterValue": { "$ref": "#/definitions/SignedMeterValueType" },
    "unitOfMeasure":    { "$ref": "#/definitions/UnitOfMeasureType" }
  }
}

Default Value Interpretation

A SampledValue with only the value field present defaults to:

  • measurand: Energy.Active.Import.Register
  • context: Sample.Periodic
  • location: Outlet
  • unit: Wh (Watt-hour)
  • multiplier: 0 (10^0 = 1)

This design saves mobile data bandwidth.

MeasurandEnumType

All possible measurement types:

Energy Measurands

Measurand Description Unit
Energy.Active.Import.Register Default. Cumulative active energy imported. Wh
Energy.Active.Export.Register Cumulative active energy exported (V2G). Wh
Energy.Active.Import.Interval Energy imported during last interval. Wh
Energy.Active.Export.Interval Energy exported during last interval. Wh
Energy.Active.Import.CableLoss Cable loss energy. Wh
Energy.Active.Import.LocalGeneration.Register Local generation register. Wh
Energy.Active.Net Net active energy. Wh
Energy.Active.Setpoint.Interval Setpoint energy during interval. Wh
Energy.Reactive.Import.Register Cumulative reactive energy imported. varh
Energy.Reactive.Export.Register Cumulative reactive energy exported. varh
Energy.Reactive.Import.Interval Reactive energy imported during interval. varh
Energy.Reactive.Export.Interval Reactive energy exported during interval. varh
Energy.Reactive.Net Net reactive energy. varh
Energy.Apparent.Import Apparent energy imported. VAh
Energy.Apparent.Export Apparent energy exported. VAh
Energy.Apparent.Net Net apparent energy. VAh

Power Measurands

Measurand Description Unit
Power.Active.Import Instantaneous active power import. W
Power.Active.Export Instantaneous active power export. W
Power.Active.Setpoint Active power setpoint. W
Power.Active.Residual Residual active power. W
Power.Reactive.Import Instantaneous reactive power import. var
Power.Reactive.Export Instantaneous reactive power export. var
Power.Offered Maximum power offered to EV. 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
Power.Factor Power factor. -

Current & Voltage Measurands

Measurand Description Unit
Current.Import Instantaneous current import. A
Current.Export Instantaneous current export. A
Current.Offered Maximum current offered to EV. A
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 Instantaneous voltage. V
Voltage.Minimum Minimum voltage. V
Voltage.Maximum Maximum voltage. V

Other & Display Measurands

Measurand Description Unit
Frequency Grid frequency. Hz
SoC State of Charge of the EV battery. %
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.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

ReadingContextEnumType

Value Description
Interruption.Begin Value at start of an interruption.
Interruption.End Value at end of an interruption.
Other Other context.
Sample.Clock Clock-aligned periodic reading.
Sample.Periodic Default. Periodic sampled reading (non-clock-aligned).
Transaction.Begin Value at start of transaction.
Transaction.End Value at end of transaction.
Trigger Value triggered by TriggerMessageRequest.

LocationEnumType

Value Description
Body Body of the Charging Station.
Cable The charging cable.
EV The Electric Vehicle.
Inlet Inlet (grid connection side).
Outlet Default. Outlet (connector side).
Upstream Upstream of the Charging Station (grid side). WARNING: privacy-sensitive data.

PhaseEnumType

Value Description
L1 Line 1 (measured on L1).
L2 Line 2 (measured on L2).
L3 Line 3 (measured on L3).
N Neutral.
L1-N Between Line 1 and Neutral.
L2-N Between Line 2 and Neutral.
L3-N Between Line 3 and Neutral.
L1-L2 Between Line 1 and Line 2.
L2-L3 Between Line 2 and Line 3.
L3-L1 Between Line 3 and Line 1.
(absent) Overall value (all phases combined).

SignedMeterValueType

For digitally signed meter data (fiscal metering / ISO 15118).

SignedMeterValueType Schema
{
  "type": "object",
  "required": ["signedMeterData", "encodingMethod"],
  "properties": {
    "signedMeterData": {
      "type": "string",
      "maxLength": 32768,
      "description": "Base64 encoded. Contains signed data in the format specified by encodingMethod."
    },
    "signingMethod": {
      "type": "string",
      "maxLength": 50,
      "description": "Method used to create the digital signature."
    },
    "encodingMethod": {
      "type": "string",
      "maxLength": 50,
      "description": "Format used to encode meter data. E.g., 'OCMF' or 'EDL'."
    },
    "publicKey": {
      "type": "string",
      "maxLength": 2500,
      "description": "Base64 encoded. Public key for signature verification."
    }
  }
}

Public Key Format (J02.FR.23)

The publicKey field, when present, is RECOMMENDED to follow the format:

<marker>:<encoding>:<content-type>:<printed-public-key>
  • <marker> = "oca"
  • <encoding> = "base16", "base32", or "base64"
  • <content-type> = "asn1"
  • <printed-public-key> = the public key as printed on the certified meter

UnitOfMeasureType

UnitOfMeasureType Schema
{
  "type": "object",
  "properties": {
    "unit": {
      "type": "string",
      "maxLength": 20,
      "default": "Wh",
      "description": "Unit of measurement. Default 'Wh' for energy measurands."
    },
    "multiplier": {
      "type": "integer",
      "default": 0,
      "description": "Exponent to base 10. E.g., multiplier=3 means value * 10^3 = value * 1000."
    }
  }
}

Computing the Actual Value

actual_value = value × 10^multiplier
value multiplier Result
1234 0 1234 Wh
1234 3 1,234,000 Wh (= 1234 kWh)
5678 -3 5.678 Wh

6. Configuration Variables

Reference

These variables are set on the Charging Station via SetVariablesRequest. The CSMS should be aware of them to understand what data to expect.

Transaction Meter Values Configuration

Variable Description Effect
SampledDataCtrlr.TxStartedMeasurands Comma-separated list of measurands for TransactionEventRequest(eventType=Started) Defines which measurands appear in transaction start messages
SampledDataCtrlr.TxUpdatedMeasurands Comma-separated list of measurands for TransactionEventRequest(eventType=Updated) every TxUpdatedInterval Defines which measurands appear in periodic transaction updates
SampledDataCtrlr.TxUpdatedInterval Interval in seconds between sampled meter data during transaction 0 = no sampled data. E.g., 300 = every 5 minutes
SampledDataCtrlr.TxEndedMeasurands Comma-separated list of measurands for TransactionEventRequest(eventType=Ended) Defines which measurands appear at transaction end. Measured every TxEndedInterval from start
SampledDataCtrlr.TxEndedInterval Interval in seconds for end-of-transaction measurands 0 = only final values

Clock-Aligned Meter Values Configuration

Variable Description Effect
AlignedDataCtrlr.Measurands Comma-separated list of measurands for clock-aligned MeterValuesRequest Defines what's in non-transaction clock-aligned readings
AlignedDataCtrlr.Interval Interval in seconds for clock-aligned readings (from midnight) 0 = disabled. 900 = every 15 min (0:00, 0:15, 0:30, ...)
AlignedDataCtrlr.TxEndedMeasurands Measurands for clock-aligned data in TransactionEventRequest(eventType=Ended) Defines clock-aligned measurands at end of transaction
AlignedDataCtrlr.TxEndedInterval Interval in seconds for clock-aligned data within TransactionEventRequest(eventType=Ended) Similar to AlignedDataCtrlr.Interval but for transaction-end messages
AlignedDataSendDuringIdle Boolean true = only send clock-aligned MeterValuesRequest when no transactions are active

Upstream Measurands Configuration

Warning: Upstream measurands may be privacy-sensitive data. May be subject to regulation and legal liability. An explicit agreement may be required.

Variable Description Effect
SampledDataUpstreamMeasurands Comma-separated list of upstream measurands Included in TransactionEventRequest(eventType=Started/Updated)
SampledDataUpstreamInterval Interval in seconds for upstream measurands How often upstream data is sampled
AlignedDataUpstreamMeasurands Comma-separated list of upstream measurands (clock-aligned) Included in clock-aligned readings
AlignedDataUpstreamInterval Interval in seconds for upstream aligned data How often upstream aligned data is sampled

Signed Meter Values Configuration

Variable Description Effect
AlignedDataSignReadings Boolean true = CS retrieves signed meter values for clock-aligned data
SampledDataSignReadings Boolean true = CS retrieves signed meter values for sampled data

Other Configuration

Variable Description Effect
SampledDataRegisterValuesWithoutPhases Boolean true = only report total energy over all phases for Energy.Active.Import.Register, not individual phases

7. Validation Rules & Business Logic

Reference

Schema Validation Checklist

For MeterValuesRequest:

  • evseId is present and >= 0
  • meterValue array is present with >= 1 element
  • MeterValue each has a valid ISO 8601 timestamp
  • MeterValue each has sampledValue array with >= 1 element
  • SampledValue each has a numeric value
  • signedMeterValue if present: signedMeterData and encodingMethod are required

For TransactionEventRequest (meter-related):

  • eventType, timestamp, triggerReason, seqNo, transactionInfo are all present
  • transactionInfo.transactionId is present (max 36 chars)
  • meterValue if present: same validation as MeterValuesRequest above

Business Logic Rules

Rule Description Action
Register monotonicity All .Register measurands for a single transaction MUST be monotonically increasing (J02.FR.16) Flag decreasing register values. Exception allowed for meter replacement.
Register continuity Register values SHOULD NOT be re-based to zero at transaction start (J02.FR.17) Compare starting register of a new transaction to ending register of the previous transaction on the same connector. Differences may indicate missing energy.
Timestamp validation MeterValue timestamps for eventType=Started/Updated must be within the current sampling interval (J02.FR.10) (event_timestamp - SampledDataTxUpdatedInterval) < meterValue.timestamp <= event_timestamp
EVSE consistency Meter values in TransactionEventRequest must relate to the EVSE of the transaction (J02.FR.22) Cross-reference reported EVSE with transaction EVSE.
Sequence completeness Use seqNo to verify all transaction events are received Track expected seqNo per transaction. Gaps indicate dropped messages.
Offline handling Messages with offline=true were queued Process, but be aware timestamps may be in the past.

Response Timing

  • MUST respond promptly to both MeterValuesRequest and TransactionEventRequest
  • Failure to respond causes the Charging Station to retry, potentially causing duplicate messages
  • Keep processing logic lightweight or process asynchronously and respond immediately

8. Configuration Examples

Reference

Recommended configurations the CSMS can push to Charging Stations via SetVariablesRequest.

Only Energy Register at Start/Stop of Transaction

SetVariablesRequest Configuration
SampledDataCtrlr.TxStartedMeasurands = ""  (empty)
SampledDataCtrlr.TxUpdatedMeasurands = ""  (empty)
SampledDataCtrlr.TxEndedMeasurands = "Energy.Active.Import.Register"
SampledDataCtrlr.TxEndedInterval = 0

What the CSMS receives:

Energy register value only at transaction end in TransactionEventRequest(eventType=Ended).

Energy Register at Start, During, and End of Transaction

SetVariablesRequest Configuration
SampledDataCtrlr.TxStartedMeasurands = "Energy.Active.Import.Register"
SampledDataCtrlr.TxUpdatedMeasurands = "Energy.Active.Import.Register"
SampledDataCtrlr.TxUpdatedInterval = 300    (every 5 minutes)
SampledDataCtrlr.TxEndedMeasurands = "Energy.Active.Import.Register"
SampledDataCtrlr.TxEndedInterval = 0

What the CSMS receives:

  • TransactionEventRequest(eventType=Started) with starting register value
  • TransactionEventRequest(eventType=Updated, triggerReason=MeterValuePeriodic) every 5 minutes with current register value
  • TransactionEventRequest(eventType=Ended) with final register value

Clock-Aligned Values During Transaction and Start/Stop at End

SetVariablesRequest Configuration
SampledDataCtrlr.TxStartedMeasurands = ""  (empty)
SampledDataCtrlr.TxUpdatedMeasurands = ""  (empty)
SampledDataCtrlr.TxEndedMeasurands = "Energy.Active.Import.Register"
SampledDataCtrlr.TxEndedInterval = 0
AlignedDataCtrlr.Measurands = "Energy.Active.Import.Register"
AlignedDataCtrlr.Interval = 300    (every 5 minutes)

What the CSMS receives:

  • Clock-aligned MeterValuesRequest every 5 minutes (when EVSE is idle) OR TransactionEventRequest with triggerReason=MeterValueClock (when in transaction)
  • TransactionEventRequest(eventType=Ended) with final register value

9. Quick Reference: CSMS Response Templates

Reference

MeterValuesResponse (J01)

MeterValuesResponse — Minimal
{}

TransactionEventResponse (J02/J03)

Minimal Acknowledgement
{}
With Running Cost
{
  "totalCost": 12.50
}
With Transaction Limits
{
  "totalCost": 12.50,
  "transactionLimit": {
    "maxCost": 50.00,
    "maxEnergy": 60000,
    "maxTime": 7200,
    "maxSoC": 80
  }
}
Full Example
{
  "totalCost": 12.50,
  "chargingPriority": 0,
  "idTokenInfo": {
    "status": "Accepted"
  },
  "transactionLimit": {
    "maxCost": 50.00,
    "maxEnergy": 60000
  },
  "updatedPersonalMessage": {
    "format": "UTF8",
    "content": "Charging at 22kW. Estimated completion: 14:30."
  }
}

OCPP 2.1 Meter Values (J01–J03) - CSMS Developer Guide. Based on OCPP 2.1 Edition 2 Specification (Part 2), Section J.