OCPP 2.0.1 Edition 4

Meter Values Flows - CSMS Developer Guide

Based on OCPP 2.0.1 Edition 4 Specification (Part 2, Section J). This guide covers all meter value flows from the CSMS (Charging Station Management System) perspective.

5 Sections
3 Use Cases
J01 - J03

1 Overview

This Functional Block describes the functionality that enables a Charging Station to send periodic, possibly clock-aligned MeterValues to the CSMS.

Meter value data can be recorded and transmitted in different ways depending on its intended purpose. The two primary use cases are:

Transaction Meter Values

Frequent (e.g. 1-5 minute interval) readings transmitted during a transaction via TransactionEventRequest (eventType = Updated). These are never sent via MeterValuesRequest.

Clock-Aligned Meter Values

Readings taken at specific clock-aligned times (e.g. every quarter hour) from fiscally certified energy meters. Sent via standalone MeterValuesRequest messages (or via TransactionEventRequest if during a transaction).

Key Distinction

Meter Value TypeDuring TransactionOutside TransactionMessage Used
Transaction Meter ValuesYes (only)NoTransactionEventRequest
(eventType=Updated)
Clock-Aligned Meter ValuesVia TransactionEventRequest
with triggerReason=MeterValueClock
Via MeterValuesRequestEither

2 Configuration Variables

The CSMS can configure meter value behavior on the Charging Station using SetVariablesRequest. These are the relevant configuration variables:

Transaction Meter Values

VariableDescription
SampledDataCtrlr.TxStartedMeasurandsComma-separated list of measurands to include in TransactionEventRequest (eventType = Started) meterValues field
SampledDataCtrlr.TxUpdatedMeasurandsComma-separated list of measurands to include in TransactionEventRequest (eventType = Updated) meterValues field, every TxUpdatedInterval seconds
SampledDataCtrlr.TxUpdatedIntervalTime in seconds between sampling of metering data during a transaction (eventType = Updated). Value of "0" means no sampled data should be transmitted
SampledDataCtrlr.TxEndedMeasurandsComma-separated list of measurands to include in TransactionEventRequest (eventType = Ended). Measurands must be taken every TxEndedInterval seconds from the start of the transaction
SampledDataCtrlr.TxEndedIntervalTime in seconds between sampling of metering data for the TransactionEventRequest (eventType = Ended) message

Clock-Aligned Meter Values

VariableDescription
AlignedDataCtrlr.MeasurandsComma-separated list of measurands to include in MeterValuesRequest PDU, every AlignedDataCtrlr.Interval seconds
AlignedDataCtrlr.IntervalSize of clock-aligned data interval in seconds. Evenly spaced intervals per day starting at 00:00:00 midnight. Value of "0" means no clock-aligned data. E.g. 900 = every 15 minutes
AlignedDataCtrlr.TxEndedMeasurandsComma-separated list of clock-aligned periodic measurands for TransactionEventRequest (eventType = Ended) PDU, every TxEndedInterval
AlignedDataCtrlr.TxEndedIntervalSize of clock-aligned data interval for TransactionEventRequest (eventType = Ended)
AlignedDataCtrlr.SendDuringIdleWhen true, only send clock-aligned meter values when there are no ongoing transactions

Additional Configuration Variables

VariableDescription
AlignedDataCtrlr.UpstreamMeasurandsMeasurands for upstream (grid connection) meter
AlignedDataCtrlr.UpstreamIntervalInterval for upstream meter readings
AlignedDataSignReadingsWhen true, Charging Station retrieves signed meter values and puts them in signedMeterValue field
SampledDataSignReadingsWhen true, Charging Station retrieves signed meter values for sampled data
SampledDataRegisterValuesWithoutPhasesWhen true, only report total energy over all phases (no individual phase values) for Energy.Active.Import.Register

Configuration Examples

Only sampled energy register values at start/stop of transaction
TxStartedMeasurands and TxUpdatedMeasurands = empty
TxEndedMeasurands = "Energy.Active.Import.Register"
TxEndedInterval = 0
Values of energy register at start, during, and end of transaction
TxStartedMeasurands = "Energy.Active.Import.Register"
TxUpdatedMeasurands = "Energy.Active.Import.Register"
TxUpdatedInterval = 300 (every 5 minutes)
TxEndedMeasurands = "Energy.Active.Import.Register"
TxEndedInterval = 0
Only clock-aligned register values during transaction and start/stop at end
TxStartedMeasurands and TxUpdatedMeasurands = empty
TxEndedMeasurands = "Energy.Active.Import.Register"
TxEndedInterval = 0
AlignedDataCtrlr.Measurands = "Energy.Active.Import.Register"
AlignedDataCtrlr.Interval = 300 (every 5 minutes)

3 Data Types & JSON Schemas

MeterValuesRequest CS → CSMS

OCPP Action: MeterValues
Direction: Charging Station → CSMS (CALL)

MeterValuesRequest Example
{
  "evseId": 1,
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 1500.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Clock",
          "location": "Outlet",
          "unitOfMeasure": {
            "unit": "Wh",
            "multiplier": 0
          }
        }
      ]
    }
  ]
}
FieldTypeRequiredDescription
evseIdintegerYesEVSE identifier (>0). Use 0 to designate the main power meter
meterValueMeterValueType[]YesArray of meter value sets (min 1 item)

MeterValuesResponse CSMS → CS

OCPP Action: MeterValues
Direction: CSMS → Charging Station (CALLRESULT)

The response body is empty (no required fields). The CSMS simply acknowledges receipt:

MeterValuesResponse Example
{}

MeterValueType

FieldTypeRequiredDescription
timestampdateTime (string)YesTimestamp for when the sampled value(s) were taken. Applies to all SampledValues within
sampledValueSampledValueType[]YesArray of sampled values (min 1 item). All values sampled at the same point in time

SampledValueType

FieldTypeRequiredDefaultDescription
valuenumberYes-The measured value
contextReadingContextEnumTypeNoSample.PeriodicReason/event triggering the reading
measurandMeasurandEnumTypeNoEnergy.Active.Import.RegisterType of measurement
phasePhaseEnumTypeNo-Phase(s) the value applies to. When absent, interpreted as overall value
locationLocationEnumTypeNoOutletWhere the measurement was sampled
signedMeterValueSignedMeterValueTypeNo-Digitally signed meter value data
unitOfMeasureUnitOfMeasureTypeNoWh (for energy)Unit and multiplier

Enumerations

ReadingContextEnumType

ValueDescription
Interruption.BeginValue at the start of an interruption
Interruption.EndValue at the end of an interruption
OtherOther context
Sample.ClockClock-aligned periodic sample
Sample.PeriodicTransaction-related periodic sample (default)
Transaction.BeginValue at the beginning of a transaction
Transaction.EndValue at the end of a transaction
TriggerValue taken in response to a TriggerMessage

MeasurandEnumType (Selected Values)

ValueUnitDescription
Current.ExportAInstantaneous current flowing from EV
Current.ImportAInstantaneous current flowing to EV
Current.OfferedAMaximum current offered to EV
Energy.Active.Import.RegisterWhEnergy imported (register, monotonic) (default)
Energy.Active.Export.RegisterWhEnergy exported (register, monotonic)
Power.Active.ImportWActive power imported
SoCPercentState of Charge of the EV battery
VoltageVAC RMS supply voltage

Note: This is a subset of available measurands. See OCPP 2.0.1 specification for the complete list.

PhaseEnumType

ValueDescription
L1Phase L1 measured against neutral
L2Phase L2 measured against neutral
L3Phase L3 measured against neutral
L1-NPhase L1 to neutral
L2-NPhase L2 to neutral
L3-NPhase L3 to neutral
L1-L2Phase L1 to L2
L2-L3Phase L2 to L3
L3-L1Phase L3 to L1

LocationEnumType

ValueDescription
BodyBody of the Charging Station
CableCharging cable
EVElectric Vehicle
InletGrid inlet (upstream)
OutletConnector outlet (default)

TransactionEventRequest — meterValue field CS → CSMS

Transaction-related meter values are sent as part of the TransactionEventRequest message in the optional meterValue field. The structure is identical to MeterValuesRequest.meterValue.

FieldTypeRequiredDescription
eventTypeTransactionEventEnumTypeYesStarted, Updated, or Ended
timestampdateTimeYesWhen the event occurred
triggerReasonTriggerReasonEnumTypeYesWhy this event was sent (e.g. MeterValuePeriodic, MeterValueClock)
meterValueMeterValueType[]NoArray of meter values (same structure as MeterValuesRequest)

4 OCPP Messages

MeterValues Message CS ↔ CSMS

Request: MeterValuesRequest CS → CSMS

Used for sending clock-aligned meter values when no transaction is running, or for sending main power meter (evseId=0) values.

Example: Clock-aligned readings from EVSE 1
[2, "msg001", "MeterValues", {
  "evseId": 1,
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 15234.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Clock",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        },
        {
          "value": 230.1,
          "measurand": "Voltage",
          "context": "Sample.Clock",
          "phase": "L1-N",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "V", "multiplier": 0 }
        }
      ]
    }
  ]
}]
Example: Main power meter (evseId=0)
[2, "msg002", "MeterValues", {
  "evseId": 0,
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 85432.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Clock",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        }
      ]
    }
  ]
}]
Response: MeterValuesResponse CSMS → CS

The CSMS always responds with an empty body to acknowledge receipt. Failing to respond will cause the CS to retry the same message.

MeterValuesResponse
[3, "msg001", {}]

TransactionEvent Message CS ↔ CSMS

Request: TransactionEventRequest (with meter values) CS → CSMS

Transaction-related meter values are always sent via TransactionEventRequest (never via MeterValuesRequest).

Example: Periodic meter values during transaction (eventType=Updated)
[2, "msg042", "TransactionEvent", {
  "eventType": "Updated",
  "timestamp": "2024-01-15T10:35:00Z",
  "triggerReason": "MeterValuePeriodic",
  "seqNo": 5,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "Charging",
    "timeSpentCharging": 300
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:35:00Z",
      "sampledValue": [
        {
          "value": 2500.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Periodic",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        },
        {
          "value": 7200.0,
          "measurand": "Power.Active.Import",
          "context": "Sample.Periodic",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "W", "multiplier": 0 }
        },
        {
          "value": 72,
          "measurand": "SoC",
          "context": "Sample.Periodic",
          "location": "EV",
          "unitOfMeasure": { "unit": "Percent", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 }
}]
Example: Transaction start with meter values (eventType=Started)
[2, "msg040", "TransactionEvent", {
  "eventType": "Started",
  "timestamp": "2024-01-15T10:30:00Z",
  "triggerReason": "Authorized",
  "seqNo": 0,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "EVConnected"
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 10000.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Transaction.Begin",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 },
  "idToken": { "idToken": "AABBCCDD", "type": "ISO14443" }
}]
Example: Transaction end with meter values (eventType=Ended)
[2, "msg050", "TransactionEvent", {
  "eventType": "Ended",
  "timestamp": "2024-01-15T11:30:00Z",
  "triggerReason": "StopAuthorized",
  "seqNo": 18,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "Idle",
    "stoppedReason": "Local",
    "timeSpentCharging": 3420
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T11:30:00Z",
      "sampledValue": [
        {
          "value": 17500.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Transaction.End",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 },
  "idToken": { "idToken": "AABBCCDD", "type": "ISO14443" }
}]
Response: TransactionEventResponse CSMS → CS

The CSMS can optionally include running cost or final cost in the response.

Example: With running cost
[3, "msg042", {
  "totalCost": 1.25
}]
Example: Simple acknowledgment
[3, "msg042", {}]
Example: Final cost at transaction end
[3, "msg050", {
  "totalCost": 3.75,
  "idTokenInfo": { "status": "Accepted" }
}]

J01 Sending Meter Values Not Related to a Transaction

Use Case Summary
Name: Sending Meter Values not related to a transaction
ID: J01
Objective: To sample the electrical meter or other sensor/transducer hardware to provide information about the Charging Station's Meter Values
Actors: Charging Station, CSMS
Prerequisite: The Charging Station is configured to send meter values every XX seconds. No transaction is running

Scenario Description

  1. The Charging Station sends a MeterValuesRequest message, for offloading Meter Values to the CSMS.
  2. Upon receipt of a MeterValuesRequest message, the CSMS responds with a MeterValuesResponse message.

Sequence Diagram

┌─────────────────┐                              ┌──────┐
│ Charging Station│                              │ CSMS │
└────────┬────────┘                              └──┬───┘
         │                                          │
         │  MeterValuesRequest(evseId, meterValue)  │
         │─────────────────────────────────────────>│
         │                                          │
         │         MeterValuesResponse()            │
         │<─────────────────────────────────────────│
         │                                          │

CSMS Handling

When the CSMS receives a MeterValuesRequest:

  1. Parse the request: Extract evseId and meterValue array
  2. Identify the EVSE: evseId > 0 refers to a specific EVSE; evseId = 0 refers to the main power meter of the Charging Station
  3. Store the meter values: For each MeterValueType in the array:
    • Record the timestamp
    • For each SampledValueType in sampledValue:
      • Store value with the associated measurand (default: Energy.Active.Import.Register)
      • Record context (default: Sample.Periodic), location (default: Outlet), phase, and unitOfMeasure
      • If signedMeterValue is present, store the signed data for audit/verification purposes
  4. Respond with MeterValuesResponse: The response body is empty ( {}). Always respond to avoid the Charging Station retrying.

Example Request/Response

MeterValuesRequest (clock-aligned readings from EVSE 1)
[2, "msg001", "MeterValues", {
  "evseId": 1,
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 15234.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Clock",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        },
        {
          "value": 230.1,
          "measurand": "Voltage",
          "context": "Sample.Clock",
          "phase": "L1-N",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "V", "multiplier": 0 }
        },
        {
          "value": 16.5,
          "measurand": "Current.Import",
          "context": "Sample.Clock",
          "phase": "L1",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "A", "multiplier": 0 }
        }
      ]
    }
  ]
}]
MeterValuesResponse
[3, "msg001", {}]

Key Requirements (CSMS)

Multiple Locations/Phases

When a Charging Station has measurands configured that can be measured on multiple locations or phases, then all possible locations and/or phases SHALL be reported.

Example Scenario

A CS capable of measuring Current.Import on:

  • Inlet (3 phases)
  • Outlet (3 phases per EVSE on both EVSEs)

With AlignedDataCtrlr.Interval = 900 (every 15 minutes), the CS 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)

J02 Sending Transaction Related Meter Values

Use Case Summary
Name: Sending transaction related Meter Values
ID: J02
Objective: To sample the energy meter or other sensor/transducer hardware to provide information about the Charging Station's transaction-related Meter Values
Actors: Charging Station, CSMS
Prerequisite: The Charging Station is configured to send meter values every XX seconds. A transaction is running
Error handling: When Offline, the Charging Station MUST queue any transaction-related messages that it would have sent to the CSMS if it had been online

Scenario Description

  1. The Charging Station sends a TransactionEventRequest (eventType = Updated) message, for offloading Meter Values to the CSMS.
  2. Upon receipt of the TransactionEventRequest message, the CSMS responds with a TransactionEventResponse message.

Sequence Diagram

┌─────────────────┐                                                              ┌──────┐
│ Charging Station│                                                              │ CSMS │
└────────┬────────┘                                                              └──┬───┘
         │                                                                          │
         │  TransactionEventRequest(eventType=Updated, transactionId, meterValues)  │
         │─────────────────────────────────────────────────────────────────────────>│
         │                                                                          │
         │                     TransactionEventResponse()                           │
         │<─────────────────────────────────────────────────────────────────────────│
         │                                                                          │

CSMS Handling

When the CSMS receives a TransactionEventRequest with eventType = Updated containing meterValue:

  1. Identify the transaction: Use transactionInfo.transactionId to locate the ongoing transaction
  2. Validate the sequence: Check seqNo to ensure message ordering and detect gaps
  3. Check if offline: If offline = true, the data was queued while the CS was offline
  4. Process meter values: For each MeterValueType in the meterValue array:
    • Record the timestamp
    • For each SampledValueType: Store value, measurand, context, location, phase, unitOfMeasure
    • Store signedMeterValue if present
  5. Validate register values: All "Register" type values (e.g. Energy.Active.Import.Register) MUST be monotonically increasing in time (except meter replacement cases)
  6. Respond with TransactionEventResponse: Always respond. Can optionally include totalCost, chargingPriority, idTokenInfo, or updatedPersonalMessage

Example Request/Response

Periodic meter value during transaction (eventType=Updated)

TransactionEventRequest
[2, "msg042", "TransactionEvent", {
  "eventType": "Updated",
  "timestamp": "2024-01-15T10:35:00Z",
  "triggerReason": "MeterValuePeriodic",
  "seqNo": 5,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "Charging",
    "timeSpentCharging": 300
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:35:00Z",
      "sampledValue": [
        {
          "value": 2500.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Sample.Periodic",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        },
        {
          "value": 7200.0,
          "measurand": "Power.Active.Import",
          "context": "Sample.Periodic",
          "location": "Outlet",
          "unitOfMeasure": { "unit": "W", "multiplier": 0 }
        },
        {
          "value": 72,
          "measurand": "SoC",
          "context": "Sample.Periodic",
          "location": "EV",
          "unitOfMeasure": { "unit": "Percent", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 }
}]
TransactionEventResponse (with running cost)
[3, "msg042", {
  "totalCost": 1.25
}]

Transaction start with meter values (eventType=Started)

TransactionEventRequest
[2, "msg040", "TransactionEvent", {
  "eventType": "Started",
  "timestamp": "2024-01-15T10:30:00Z",
  "triggerReason": "Authorized",
  "seqNo": 0,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "EVConnected"
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T10:30:00Z",
      "sampledValue": [
        {
          "value": 10000.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Transaction.Begin",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 },
  "idToken": { "idToken": "AABBCCDD", "type": "ISO14443" }
}]

Transaction end with meter values (eventType=Ended)

TransactionEventRequest
[2, "msg050", "TransactionEvent", {
  "eventType": "Ended",
  "timestamp": "2024-01-15T11:30:00Z",
  "triggerReason": "StopAuthorized",
  "seqNo": 18,
  "transactionInfo": {
    "transactionId": "txn-abc-123",
    "chargingState": "Idle",
    "stoppedReason": "Local",
    "timeSpentCharging": 3420
  },
  "meterValue": [
    {
      "timestamp": "2024-01-15T11:30:00Z",
      "sampledValue": [
        {
          "value": 17500.0,
          "measurand": "Energy.Active.Import.Register",
          "context": "Transaction.End",
          "unitOfMeasure": { "unit": "Wh", "multiplier": 0 }
        }
      ]
    }
  ],
  "evse": { "id": 1, "connectorId": 1 },
  "idToken": { "idToken": "AABBCCDD", "type": "ISO14443" }
}]
TransactionEventResponse (with final cost)
[3, "msg050", {
  "totalCost": 3.75,
  "idTokenInfo": { "status": "Accepted" }
}]

Key Requirements (CSMS)

Offline Behavior

When the Charging Station is offline during a transaction:

J03 Charging Loop with Metering Information Exchange (ISO 15118)

Use Case Summary
Name: Charging Loop with metering information exchange
ID: J03
Reference: ISO15118-1 F1
Objective: See ISO15118-1, use case Objective F1, page 37
Actors: EV, CSMS, Charging Station
Prerequisite: If authorization per Functional Block C is applied, it SHALL be finished successfully

Scenario Description

This use case combines ISO 15118 communication between the EV and Charging Station with OCPP communication between the Charging Station and CSMS:

ISO 15118 phase:

  1. 1a (AC Charging): The EV sends a ChargingStatusReq message to the Charging Station, which returns a ChargingStatusRes containing the meter value from the fiscal meter.
    1b (DC Charging): The EV sends a CurrentDemandReq message to the Charging Station, which returns a CurrentDemandRes containing the meter value from the fiscal meter.
  2. The EV sends a MeteringReceiptReq to the Charging Station to acknowledge receipt of the meter value.

OCPP phase:

  1. The Charging Station sends a TransactionEventRequest (eventType = Updated, with signed meter values) to the CSMS.
  2. The CSMS responds with a TransactionEventResponse.

Sequence Diagram

┌────┐         ┌─────────────────┐                                                            ┌──────┐
│ EV │         │ Charging Station│                                                            │ CSMS │
└─┬──┘         └────────┬────────┘                                                            └──┬───┘
  │                     │                                                                        │
  │ [if AC Charging]    │                                                                        │
  │ ChargingStatusReq() │                                                                        │
  │────────────────────>│                                                                        │
  │                     │                                                                        │
  │ ChargingStatusRes(MeterInfoRecord{MeterId,                                                   │
  │   MeterReading, MeterStatus,                                                                 │
  │   SignedMeterReading, timeStamp},                                                            │
  │   ReceiptRequired: True)                                                                     │
  │<────────────────────│                                                                        │
  │                     │                                                                        │
  │ MeteringReceiptReq( │                                                                        │
  │   Signature to      │                                                                        │
  │   confirm data)     │                                                                        │
  │────────────────────>│                                                                        │
  │                     │                                                                        │
  │ MeteringReceiptRes()│                                                                        │
  │<────────────────────│                                                                        │
  │                     │                                                                        │
  │                     │  TransactionEventRequest(eventType=Updated,                             │
  │                     │    transactionID, timestamp,                                            │
  │                     │    chargingState=Charging, Signed metervalues)                          │
  │                     │───────────────────────────────────────────────────────────────────────> │
  │                     │                                                                        │
  │                     │                     TransactionEventResponse()                          │
  │                     │<───────────────────────────────────────────────────────────────────────│
  │                     │                                                                        │

CSMS Handling

When the CSMS receives a TransactionEventRequest with signed meter values from an ISO 15118 charging session:

  1. Process the transaction event the same as J02 — store the meter values including signedMeterValue data
  2. Store signed meter data: The signedMeterValue field in SampledValueType contains:
    • signedMeterData: Base64 encoded signed data from the fiscal meter
    • signingMethod: The digital signature method used
    • encodingMethod: How meter values were encoded before signing
    • publicKey: Base64 encoded public key for signature verification
  3. Respond with TransactionEventResponse: Same as J02

SignedMeterValueType

FieldTypeRequiredDescription
signedMeterDatastring (max 2500)YesBase64 encoded signed data (may contain timestamps, customer references, etc.)
signingMethodstring (max 50)YesMethod used to create the digital signature
encodingMethodstring (max 50)YesMethod used to encode meter values before signing
publicKeystring (max 2500)YesBase64 encoded public key (sending depends on PublicKeyWithSignedMeterValue config)

Key Takeaway for CSMS

CSMS Implementation Checklist

For J01 (MeterValuesRequest handling)
  • Register handler for MeterValues action
  • Parse evseId and meterValue array from request
  • Handle evseId = 0 as the main power meter (Charging Station level)
  • Handle evseId > 0 as specific EVSE meter values
  • Store each MeterValueType with its timestamp and all SampledValue entries
  • Apply defaults when optional fields are absent (measurand=Energy.Active.Import.Register, context=Sample.Periodic, location=Outlet, unit=Wh, multiplier=0)
  • Store signedMeterValue when present
  • Always respond with empty MeterValuesResponse ({})
For J02 (TransactionEventRequest with meter values)
  • In the TransactionEvent handler, check for the optional meterValue field
  • Associate meter values with the transaction (via transactionInfo.transactionId)
  • Handle all three eventTypes (Started, Updated, Ended) with their respective meter value contexts
  • Validate seqNo for message ordering and gap detection
  • Handle offline = true events (queued data from offline period)
  • Validate that "Register" measurands are monotonically increasing
  • Store signed meter values when present
  • Respond with TransactionEventResponse — optionally including totalCost for running cost or final cost at end
  • Handle multiple messages with same timestamp (large meter data split across messages)
For J03 (ISO 15118 signed meter values)
  • No special handling needed beyond J02
  • Store signedMeterValue data for audit/verification
  • Be prepared to receive signed meter values in TransactionEventRequest messages

OCPP 2.0.1 Meter Values Flows - CSMS Developer Guide. Based on OCPP 2.0.1 Edition 4 Specification (Part 2, Section J).