Ev15118¶
Handwritten Documentation¶
Ev15118¶
EV-side ISO 15118 EVCC built on the libiso15118 ev::Controller. It
provides the ISO15118_ev interface and drives a DC or AC session against a
SECC such as Evse15118D20 or EvseV2G.
The v2g_messages notification identifies received responses for all three
protocol generations, including PowerDeliveryRes before welding detection.
It does not report transmitted requests.
Protocols¶
The SAP offer carries the protocols supported_protocols lists, a
comma-separated list of ISO15118_20, ISO15118_2 and DIN70121 in
priority order: the first entry is offered with priority 1. For example
ISO15118_2,ISO15118_20 prefers ISO 15118-2 over ISO 15118-20. The list is
empty unless set, so a configuration offers only the protocols it names. The
module fails at startup when the list is empty, names an unknown protocol, or
names one twice.
ISO 15118-20 (AC, AC BPT, AC DER IEC, AC DER SAE, DC, DC BPT), EIM, plaintext or TLS 1.3 with a client certificate.
ISO 15118-2 (AC and DC), EIM or Plug & Charge (Contract). PnC needs TLS [V2G2-632]: with
enable_pncand TLS the EV offersPnCandEIM, and presents the configured contract certificate in PaymentDetails; without a contract certificate (or withpnc_force_cert_install) it runs a CertificateInstallation with the OEM provisioning certificate first, if the SECC offers installation in ServiceDetail for ServiceID 2 (ParameterSetID 1). A FAILED ServiceDetail response stops the session. If a successful response does not offer installation, it uses an available contract, or EIM if offered, and stops if neither is usable. An enforced Contract payment option remains selected without a certificate. TLS 1.2 is used for -2; atls_versionpinned to"1.3"runs it over TLS 1.3 anyway, and the module warns at startup about the deviation. An installed contract is kept inpnc_contract_store_dirwhen that is set, and later sessions present it instead of the configured contract.DIN SPEC 70121 (DC, plaintext only), no authorization step.
The ISO 15118-2 / DIN EVCCID is the 6 byte MAC of the resolved device (the
evcc_id string is ISO 15118-20 only). The EnergyTransferMode of
start_charging selects the -2 / DIN transfer mode; the AC values are taken
from the iso2_ac_* options. A BPT or DER mode has no -2 / DIN equivalent and
degrades to the matching unidirectional mode, with a warning when the pre-20
generation is offered at all.
Which payment option the EV picks is config driven, because the EvManager
default payment option is auto: with enable_pnc and TLS the EV prefers
Contract whenever the SECC offers it, and the -2 engine falls back to EIM when
it does not. SelectedPaymentOption only overrides that per session; an
explicit ExternalPayment turns the preference off for that session, an
explicit Contract keeps it on. enforce_payment_option makes the EV
select Contract even when the SECC does not offer it (negative testing).
Without enable_pnc the EV offers EIM only.
The session runs over plain TCP or TLS (tls / tls_version, see
Transport security). The AC DER IEC and AC DER SAE services are also
negotiated (assuming a three-phase inverter relay). The EV negotiates DER functions but never executes one; it
publishes what was negotiated and received (see Published DER variables).
Bidirectional power transfer (BPT) is negotiated for both AC_BPT and DC_BPT in
Dynamic control mode. The advertised discharge limits come from the
*_discharge_* config settings; set_bpt_dc_params overrides the
configured DC discharge power and current. Like set_dc_params it states
vehicle limits: they reach a running DC_BPT or MCS_BPT session at once and stay
for every later BPT session until the next set_bpt_dc_params. A field it
leaves out keeps its previous value. During a DC_BPT or MCS_BPT session the
update is validated with the session’s parameters and rejected whole when
invalid. These settings are magnitudes: the EV sends
discharge limits, var injection limits and excited discharge powers negated, as
ISO 15118-20 [V2G20-1035] requires. AC_BPT assumes a three-phase inverter relay.
Reverse power flow itself is driven entirely by the SECC’s target-power
directives; the EVSE’s advertised discharge limits are logged for visibility.
Transport security¶
tls picks whether TLS runs: off requests no TLS in SDP, prefer
requests it and accepts a plaintext SECC, require rejects an SDP response
without TLS. off runs ISO 15118-20 and ISO 15118-2 over plain TCP; for
ISO 15118-20 this deviates from [V2G20-2677] and is meant for testing (the
config-sil-*-d20-plaintext.yaml configurations use it), and Plug & Charge
over plain TCP additionally needs allow_pnc_without_tls. tls_version
picks the version when TLS runs:
autooffers TLS 1.3, with the vehicle chain loaded for mutual TLS, when the SAP offer holds ISO 15118-20, and TLS 1.2 when it holds ISO 15118-2. An explicitadvertised_app_protocolslist counts as the offer. When the vehicle chain or key is not configured, missing or unreadable at connect, 1.3 is dropped and the EV logs why, once per reason. When no version is leftstart_chargingis rejected with an error naming the enabled protocols and why 1.3 is unavailable; a chain file found unusable only at connect stops the session there with the same error. After the handshake the SAP offer is rebuilt for the negotiated version: only ISO 15118-20 over TLS 1.3, only ISO 15118-2 over TLS 1.2. When no enabled protocol is left the EV closes the connection and stops with an error naming the version and the enabled protocols; it never falls back to plaintext. An explicitadvertised_app_protocolslist is never narrowed after the handshake."1.2"and"1.3"pin that version and offer every enabled protocol over it. ISO 15118-2 over TLS 1.3 and ISO 15118-20 over TLS 1.2 deviate from the standards and are named in a startup warning. A pinned"1.3"offers TLS 1.3 even without a vehicle chain.
DIN SPEC 70121 is never offered over TLS.
Configuration¶
Option |
Default |
Description |
|---|---|---|
|
|
Ethernet device used for high-level communication. |
|
|
EVCC identifier sent to the SECC, 1 to 255 characters. A MAC address and a
vehicle identifier ( |
|
|
Response watchdog timeout in milliseconds. |
|
|
Bound on the ISO 15118-20 authorization loop. The EV re-sends
|
|
|
Preferred charge-loop control mode, |
|
|
Comma-separated SAP offer in priority order, from |
|
|
|
|
|
Accept the deviation from the standard and present a contract over a
session with no transport security. |
|
|
|
|
|
Verify the SECC chain against the V2G root. |
|
|
Export the TLS session keys. Testing and simulation only. |
|
|
Output directory for the TLS key log file. |
|
|
Directory holding the EV certificates and keys. Each certificate and key
path below that is left empty resolves under it, written |
|
|
V2G root certificate. Empty resolves to
|
|
|
Vehicle certificate chain, leaf first. Empty resolves to
|
|
|
Vehicle leaf private key. Empty resolves to
|
|
|
File holding the vehicle leaf key password. Empty resolves to
|
|
|
ISO 15118-2 |
|
|
ISO 15118-2 |
|
|
ISO 15118-2 |
|
|
ISO 15118-2 |
|
|
Offer ISO 15118-2 Plug & Charge (Contract) next to EIM and prefer Contract
whenever the SECC offers it. Requires TLS; without it the EV warns and
falls back to EIM only, unless |
|
|
One PEM file holding the whole contract (MO) certificate chain, leaf
first. Empty resolves to |
|
|
Contract leaf private key; signs the PnC AuthorizationReq. Empty resolves
to |
|
|
File holding the contract leaf key password. Empty resolves to
|
|
|
OEM provisioning certificate; signs CertificateInstallationReq and holds
the static ECDH key that decrypts the delivered contract key. Empty
resolves to |
|
|
OEM provisioning private key. Empty resolves to
|
|
|
File holding the OEM provisioning key password. Empty resolves to
|
|
|
Run a CertificateInstallation even when a contract certificate is configured. Requires the SECC to offer the Certificate service and its installation parameter set in ServiceDetail. |
|
|
Directory that keeps an installed contract as |
|
|
Number of AC lines the EV draws on, 1 or 3. Selects the connector. On a
single-phase connector it divides the advertised totals below down to one
line’s share. A |
|
|
Advertised AC maximum charge power in watts, as a total across
|
|
|
Advertised AC minimum charge power in watts, as a total across
|
|
|
Declare support for the IEC OverFrequencyWattMode DER control function. |
|
|
Declare support for the IEC UnderFrequencyWattMode DER control function. |
|
|
Declare support for the IEC VoltWattMode DER control function. |
|
|
Declare support for the IEC VoltVarMode DER control function. |
|
|
Declare support for the IEC WattVarMode DER control function. |
|
|
Declare support for the IEC WattCosPhiMode DER control function. |
|
|
Declare support for the IEC DSOQSetpointProvision DER control function. |
|
|
Declare support for the IEC DSOCosPhiSetpointProvision DER control function. |
|
|
Declare support for the IEC DCInjectionRestriction DER control function. |
|
|
Declare support for the IEC ZeroCurrentMode DER control function. |
|
|
Declare support for the IEC OverVoltageFaultRideThroughMode DER control function. |
|
|
Declare support for the IEC UnderVoltageFaultRideThroughMode DER control function. |
|
|
Stop the session if no AC_DER_IEC parameter set fits the supported DER functions. |
|
|
Advertised AC maximum discharge power in watts (AC_BPT, AC_DER_IEC and
AC_DER_SAE), as a total across |
|
|
Advertised AC minimum discharge power in watts (AC_BPT, AC_DER_IEC and
AC_DER_SAE), as a total across |
|
|
Advertised DC maximum discharge power in watts (BPT). |
|
|
Advertised DC minimum discharge power in watts (BPT). |
|
|
Advertised DC maximum discharge current in amperes (BPT). |
|
|
JSON file describing the EV inverter for AC_DER_SAE (see SAE inverter profile). Empty uses the built-in profile. A file that fails to parse makes the module fail at startup. |
|
|
ChargeParameterDiscovery rounds the EV drives before it reports
|
|
|
Stop the session on a structurally invalid DER control block from the SECC instead of warning and continuing. AC_DER_SAE only. |
Configurations written for PyEvJosev¶
Ev15118 replaces the PyEvJosev EV module. A config_module written for
PyEvJosev maps onto Ev15118 as follows. A key with no Ev15118 equivalent is
logged by the manager as an unknown config entry and ignored, so remove it.
PyEvJosev key |
Ev15118 |
|---|---|
|
Same key, same meaning. |
|
|
|
|
|
None. The service is the energy transfer mode of |
|
|
|
Same key. Ev15118 only reads it; a contract a CertificateInstallation
delivers is kept in |
|
None. Ev15118 selects no value-added services. |
supported_protocols has no usable default; the module refuses to start
until it lists at least one protocol. A migrated configuration offers
ISO 15118-20 only when it lists ISO15118_20.
DER control function negotiation¶
For the AC DER IEC service the EV declares which IEC DER control functions it
supports through the der_* options above; these form a bitmask carried in the
ServiceDetail exchange. Among the SECC’s Dynamic parameter sets the EV selects
the first whose declared functions are a subset of the supported set (a set with
no DERControlFunctions parameter counts as compatible). A mask carrying bits
above the functions the EV models names functions it cannot honor, so such a set
is not a subset even when its remaining bits are supported. When no offered set
fits, der_stop_on_unsupported_functions decides the outcome: true stops
the session cleanly, while false proceeds with the first Dynamic set and warns
about the unsupported functions. At runtime, a DSO setpoint (Q or cos phi) that
arrives in a charge-loop response without the matching function having been
negotiated is dropped before the directive is surfaced; all other fields pass
through unchanged.
For the AC DER SAE service (ISO 15118-20 AMD1 Annex M) the EV describes its inverter in the ChargeParameterDiscovery request; the SECC enables functions in its responses and the EV acknowledges them.
SAE inverter profile¶
The file named by sae_inverter_profile_path is one JSON object. Every key is
optional and keeps its built-in default when absent; an unknown or repeated key,
a wrong JSON type, an out-of-range number or an illegal enum string fails the
parse. The parsed profile, absent keys at their defaults, is then checked with
libiso15118’s validate_sae_profile (voltage window, frequency, power factors,
identity lengths, supported modes and totals); a problem fails the module at
startup, naming the key. Powers, var, VA and siemens values are totals across
ac_phase_count lines.
Identity strings, at most 32 bytes:
inverter_sw_version,inverter_hw_version(absent by default),inverter_manufacturer,inverter_model,inverter_serial_number.supported_modes: array of SAE function names, which must include"charge"and"discharge". The names are those of libiso15118’ssae::SAE_FUNCTION_NAMES, one per AMD1 Table M.6 bit:charge,discharge,enter service,constant power factor under excited,constant power factor over excited,constant var,constant watt,frequency droop,over frequency may trip curve,over frequency must trip curve,over voltage may trip curve,over voltage momentary cessation trip curve,over voltage must trip curve,under frequency may trip curve,under frequency must trip curve,under voltage may trip curve,under voltage momentary cessation trip curve,under voltage must trip curve,limit maximum discharge power,evse target reactive power,evse target active power,volt var,volt wattandwatt var.Numbers, unit in the key suffix:
max_apparent_power_{charging,discharging}_var_{absorption,injection}_va,max_var_{absorption,injection}_{charging,discharging}_var,reactive_susceptance_s,over_excited_discharge_power_w,under_excited_discharge_power_w,nominal_voltage_v,maximum_voltage_v,minimum_voltage_v,nominal_voltage_offset_v,nominal_frequency_hz; and the ratiosover_excited_power_factorandunder_excited_power_factor, in (0, 1].Unsigned integers:
useable_watt_hours,minimum_charging_duration_s,duration_maximum_charge_rate_s,duration_maximum_discharge_rate_s, andj3072_certification_datein seconds since the Unix epoch.j3072_certified: boolean.Enum strings:
ieee1547_normal_category(CategoryA,CategoryB),ieee1547_abnormal_category(CategoryI,CategoryII,CategoryIII),operational_state(On,Off),connection_status(Connected,Disconnected).
Published DER variables¶
der_negotiated_functions: the negotiated functions, with theflavor(AC_DER_IECorAC_DER_SAE). For AC_DER_IEC this is the demand of the selected parameter set iniec_functions(DerIecFunction), published once from ServiceDetail; withoutder_stop_on_unsupported_functionsthe fallback set can demand functions the EV does not support. For AC_DER_SAE it is the enabled modes the EV echoes insae_functions(DerSaeFunction), published every ChargeParameterDiscovery round and when the charge loop changes the set. Theflavoris the annex the session runs, whatever energy modestart_chargingasked for. A resume continues the retained session at ChargeParameterDiscovery: a resumed AC_DER_SAE session publishes its enabled modes again, and a resumed AC_DER_IEC session, which skips ServiceDetail, publishes nothing and keeps the paused session’s value.der_control_received: a summary of each DER control block the SECC sends, with theflavorand thesource(ChargeParameterDiscoveryorChargeLoop). SAE blocks carrypermit_service,enabled_functions(DerSaeFunction) and anyproblems.enabled_functionslists what the EV has enabled after the block, limited to the functions it supports, the set it echoes next; a charge loop block omits the functions it does not update and those stay as they were. A block that enables functions the EV does not support names them inproblems, which never stops the session. A block that stops the session underder_stop_on_invalid_controlis still published, with its problems and the set the EV last held, before the session ends. IEC Dynamic charge loop blocks carry the DSO Q and cos phi setpoints when present; the first of a session is published, and a later one only when its setpoints change. IEC Scheduled charge loop blocks are not published.ac_evse_target_power: the Dynamic charge loop targets, for AC_DER_IEC and AC_DER_SAE as for plain AC. AC_DER_IEC in Scheduled mode does not publishac_evse_target_power.
update_present_values also takes present_frequency in Hz and
der_alarm_status (AMD1 Table M.9), both for AC_DER_SAE, where the voltage is
the measured grid voltage. start_charging clears the voltage, active power,
frequency and DER alarm status, so values reported before it are discarded; a
voltage or frequency not reported since falls back to the profile’s nominal
value.
Departure time and requested energy¶
start_charging takes DepartureTime in seconds from the call and
EAmount in kWh. Both must be finite and not negative; 0 states nothing.
An EAmount above 0 is the session’s energy request, in Wh on the wire: the
ISO 15118-2 AC EAmount, the ISO 15118-2 DC and DIN SPEC 70121
EVEnergyRequest, the ISO 15118-20 Dynamic ScheduleExchange and Dynamic
charge loop target and maximum energy, and the Scheduled ScheduleExchange
EVTargetEnergyRequest. The minimum energy is always 0. With EAmount 0,
optional fields are left out and mandatory ones fall back: ISO 15118-2 AC to
iso2_ac_e_amount_wh, the ISO 15118-20 Dynamic fields to the
energy_capacity of set_dc_params, whatever the energy service.
ISO 15118-2 caps EAmount and EVEnergyRequest at 200000 Wh
([V2G2-832]), the configured fallback included; DIN SPEC 70121 caps
EVEnergyRequest at 32767000 Wh, the largest value its PhysicalValueType
carries. A capped value is sent at the maximum and logged as a warning once per
session. ISO 15118-20 has no cap.
A DepartureTime above 0 is sent as the seconds left until departure, counting
down, in the ISO 15118-2 AC and DC ChargeParameterDiscovery, the ISO 15118-20
ScheduleExchange of either control mode and the ISO 15118-20 Dynamic charge
loops. ISO 15118-2 sends 0 once the departure has passed. ISO 15118-20 requires
a DepartureTime above 0 ([V2G20-2103]), so a departure that is not stated or has
passed is left out where optional, and the mandatory Dynamic ScheduleExchange
DepartureTime is sent as 4294967295, no deadline.
Limitations¶
The implementation has a deliberately narrow scope:
The requested energy is static. The energy request stays what
start_chargingstated for the whole session; energy already delivered is not subtracted from it (see Departure time and requested energy).DC, MCS and AC only.
start_chargingaccepts DC, DC BPT, MCS, MCS BPT, AC single/three-phase, AC BPT, AC DER IEC and AC DER SAE energy-transfer modes; WPT sessions are not supported. MCS is the megawatt DC service of ISO 15118-20: the same DC parameter discovery, cable check, pre-charge and charge loop under a different service id, so it rides the DC states and has no ISO 15118-2 or DIN equivalent.DER functions are never executed. Received DER control blocks, except IEC Scheduled ones, are published as summaries; acting on them is the consumer’s job. DER curves dictated in
DER_AC_ChargeParameterDiscoveryResare logged, and the summary carries none of their values. The three-phase inverter relay use case is assumed.AC DER SAE is Dynamic only. A preferred Scheduled control mode is ignored for that service.
Plug & Charge is ISO 15118-2 only. ISO 15118-20 authorization is EIM only. An installed contract is persisted only to
pnc_contract_store_dir, not toEvseSecurity.Dynamic BPT only. BPT is negotiated in Dynamic control mode; reverse power flow follows SECC targets. SAE J2847/2 (
enable_sae_j2847_v2g_v2h) is not implemented.
Threading¶
A single worker thread, started from ready(), runs one V2G session at a time.
start_charging hands a request to the worker; the worker constructs the
ev::Controller and runs its event loop until the session ends, then waits for
the next request. Session state is guarded by a monitor so command handlers
and the worker coordinate safely, including during module teardown.
start_charging returns false, and starts nothing, when the worker is not
running, a session is active, the energy transfer mode is unsupported, the HLC
interface is missing, or the session configuration is invalid. An invalid
configuration includes a protocol offer left empty by the requested service or
transport, for example DIN SPEC 70121 alone for an AC mode or over TLS, and a DC
or MCS mode before set_dc_params gave a positive maximum power, current and
voltage.
set_dc_params merges the fields it carries into the stored values; a field
it leaves out keeps its previous value. The merged values are validated as a
whole: an invalid update is logged and rejected, and neither stored nor pushed
to a running session. set_fault is not supported and logs a warning. A
session that ends publishes ev_power_ready false before
v2g_session_finished. A session that fails to start after
start_charging returned true still ends with v2g_session_finished.
pause_charging ends the session with SessionStop(Pause); the paused
session is stored and handed to the next ev::Controller as
ev::config::EvConfig::resume. stop_charging and abort_charging discard it.
A stop from either side outranks a pause: when the charger terminates while a pause
is pending, or stop_charging arrives before the paused SessionStop is sent,
the session terminates and nothing is kept for a resume.
In ISO 15118-20 a pause requested before PowerDelivery(Start) terminates the
session as well [V2G20-2644].
cp_state_changed is latched and replayed to every new controller, and the
first report switches the CP-dependent checks (the DC cable check) on. E or F
during a session terminates it without SessionStop, as abort_charging does
[V2G2-737], and cancels a session that was accepted but has not started yet.
For ISO 15118-2 (AC and DC), DIN SPEC 70121 (DC), and ISO 15118-20 (DC and MCS), an accepted
PowerDelivery(Stop) response publishes power_delivery_stopped before
WeldingDetection or SessionStop. The EV may then open its contactor and set CP B
while V2G shutdown continues. ISO 15118-20 AC does not publish this event.
For ISO 15118-2 AC, ac_evse_max_current publishes the EVSEMaxCurrent offered
in ChargeParameterDiscovery and reported in each ChargingStatus response that
carries it. ISO 15118-20 offers AC power, not current, and does not publish it.
DC welding detection polls until the reported voltage is strictly below 60 V.
If voltage remains unsafe for 20 accepted responses or 10 seconds, Ev15118 logs
and publishes welding_detection_failed with the response count as cycles
and the last reported voltage as last_voltage_V, left out when no response
was accepted, then attempts SessionStop with termination,
even when a pause was requested. DIN has no pause field on the wire; a failed
welding check prevents retaining its session for resume. ISO 15118-20 closes both
safe and failed checks with Processing Finished, then sends SessionStop after
its response. Each request waits for the configured message timeout or the
protocol’s message timeout when none is configured. The welding deadline does
not extend an outstanding request’s response deadline. A safe answer received
after the welding deadline still counts as safe and preserves a requested pause.
A missing response ends the session without SessionStop. In ISO 15118-2 and DIN,
it also reports welding failure. In ISO 15118-20, it reports welding failure
only before the Processing Finished request. A missing response to that request
leaves the settled result unchanged: a safe check reports no failure, and a
failed check is reported only once.