uhi22 / pyPLC

Electric vehicle CCS charging investigations with Python
GNU General Public License v3.0
125 stars 29 forks source link
ccs charging charging-stations electric-vehicles homeplug iso15118 pev

CCS hacking: Electric car charging experiments with Python and PLC network adaptors

Goal

This project tries to use cheap powerline network adaptors for communication with electric cars charging system.

There are three different use cases, where this project can be helpful:

  1. Sniffing the traffic between an CCS charger and a car. For instance to measure which side is the limiting element for reduced charging power. In this project, we call this mode ListenMode.
  2. Building a charger for CCS or for AC with digital communication. We call this EvseMode. EvseMode manual
  3. Building a charging unit for a car which does not support powerline communication. Let's call it PevMode.

News / Change History / Functional Status

2023-06-29 v0.9 Released

Highlights:

Main improvements between v0.8 and v0.9:

2023-05-22 v0.8 Released

Main improvements between v0.7 and v0.8:

2023-05-03 First real charging session

Celeron55 is the winner. He managed to combine all the prerequisits, to have the world wide first pyPlc charging session. Congratulations and thanks for the great contribution. https://openinverter.org/forum/viewtopic.php?p=56188&sid=9579fd29268d0e332c81ed528f59f09b#p56188

2023-04-19 v0.7 Released

Main improvements between v0.6 and v0.7:

2023-04-16 EvseMode brings the Ioniq to close the contactors

With simulated rising EVSEPresentVoltage in the PreChargeResponse, the Ioniq indeed closes the contactors, without the need to feed physical voltage to the CCS DC inlet pins. This is surprising, because - at least for ISO - the specification says that a physical measurement shall be done. The Ioniq does not, it just relys on the reported voltage on the charger. After closing the contacts, there is the accu voltage on the CCS. Not yet tested, whether it is possible to draw some current out of the vehicle. Log here: results/2023-04-16_at_home_Ioniq_in_currentDemandLoop.pcapng Docu here: EvseMode manual

2023-03-03 v0.6 Tea-Time on Alpitronics charger

Made a tea, using the RaspberryPi3 and tpLink modem on Alpitronics hypercharger. Pictures here: https://openinverter.org/forum/viewtopic.php?p=53848#p53848

2023-02-27 PEV mode with OLED-display works on headless Raspberry

2022-12-21 v0.5 Light-bulb-demo-charging works on multiple chargers

2022-12-20 Measurement of inlet voltage works

2022-12-13 v0.4 On Compleo, Light Bulb survives 400V cable check and PreCharge

2022-12-02 v0.3 On Alpitonics until ChargeParameterDiscovery

2022-11-25 v0.2 On ABB charger until ChargeParamDiscoveryRequest

2022-11-15 [PevMode] Draft of SLAC sequencer

In PevMode, the software runs through the SLAC sequence with a simulated Evse. After SLAC is finished, we send a software version request broadcast message, to find out, whether we have at least two homeplug modems in the network (one for the car and one for the charger). If this is fulfilled, we should use the SDP to discover the chargers IPv6 address. But this is not yet implemented.

2022-11-11 [EvseMode] Ioniq in the PreCharge loop

The EVSE state machine, together with the EXI decoder/encoder, is able to talk to the Ioniq car until the PreCharge loop. The car terminates the loop after some seconds, because the intended voltage is not reached (no physical electricity connected to the charge port). Maybe it is possible to convince the car to close the relay, just by pretending "voltage is reached" in the PreCharge response. But maybe the car makes a plausibilization with the physical voltage, then further development would require a physical power supply.

2022-11-09 [EvseMode][PevMode] Exi decoder first steps working

Using EXI decoder/encoder from basis https://github.com/Martin-P/OpenV2G and created fork https://github.com/uhi22/OpenV2Gx to provide a command-line interface, which can be used by the python script. The OpenV2G includes generated source code for four xml schemas (Handshake, DIN, ISO1, ISO2), provided by Siemens. Seems to be good maintained and is very efficient, because the decoder/encoder are directly available as C code, dedicated for each schema. This skips the slow process of reading the schema, parsing it, creating the grammer information. On Windows10 notebook, measured 15ms for decoder run from python via command line. The OpenV2G was compiled on Windows10 using the included makefile, using the mingw32-make all. The OpenV2G decoder/encoder code reveals some differences between the different schemas (DIN versus ISO). As starting point, only the DIN schema is considered in the command line interface and python part.

The python part now contains the charging state machines for car and charger, as draft.

Using the TPlink and Win10 laptop as evse, connected to Ioniq car, the python script successfully succeeds to SLAC, TCP connection, schema handshake, SessionSetup, ServiceDiscovery, ServicePaymentSelection. It stops on ChargeParameterDiscovery, most likely to missing or wrong implementation. Results (log file and pcap) are stored in https://github.com/uhi22/pyPLC/tree/master/results.

As summary, the concept with the python script together with the compiled EXI decoder works. Further efforts can be spent on completing the missing details of the V2G messages.

2022-10-26 [ListenMode] Network/AVLN is established

Using the TPlink in EVSE mode and Win10 laptop, listening to a communication setup between real car and real alpitronics charger, the python script successfully extracts the NID and NMK from the SLAC_MATCH response, sets this information into the TPlink, and the TPlink turns three LEDs on. Means: Network established. When we send a broadcast software version request, we get three responses: One from the TPlink, one from the PLC modem of the car, and one from the PLC modem of the charger. This confirms, that the network is established. But: From the higher level communication (IPv6, UDP, TCP) we see only the broadcast neighbor solicitation at the beginning. The remaining traffic is hidden, most likely because the TPlink "too intelligent", it knows who has which MAC address and hides traffic which is not intended for the third participant in the network. Trace in results/2022-10-26_WP4_networkEstablishedButHiddenCommunication.pcapng

2022-10-21 [EvseMode] SLAC, SDP and ICMP are working

Using the TPlink and Win10 laptop as evse, the python script runs successfully the SLAC and SDP (SECC discovery protocol). Afterwards, the car uses neighbor solicitation (ICMP) to confirm the IPv6 address, and the Win10 responds to it. The car tries to open the TCP on port 15118, this is failing because of missing implementation of the listener on PC side.

2022-10-19 [ListenMode] Sniffing mode not yet working with the TPlink adaptors

2022-10-19 [EvseMode] Communication/AVLN with Ioniq car established

Discussion and Wiki

See openinverter forum https://openinverter.org/forum/viewtopic.php?p=37085#p37085 and the openinverter wiki: https://openinverter.org/wiki/CCS_EVCC_using_AR7420

Quick start / overview

Architecture

architectural overview

Hardware preparation

See Hardware manual

Configuration of the PLC adaptor

The factory settings of the Homeplug PLC adaptor do not in all cases support the requirements of the communication with the car, e.g. the SLAC messages. In detail, the adaptors are supporting HomePlugAV, but we need HomePlugGP (Green Phy). This is similar, but not the same. Fortunately, the supplier of the chipset is aware of this topic, and provides some smart helper tools. http://github.com/qca/open-plc-utils It is worth to read its documentation, starting in docbook/index.html, this contains all what we need for the next steps. A more detailled description and discussion is available in https://openinverter.org/forum/viewtopic.php?p=55120#p55120.

Step-by-Step

(Tested on Linux/Raspbian on a raspberryPi 3)

Clone the http://github.com/qca/open-plc-utils to your raspberry (or other linux computer).

Connect the homeplug modem using an ethernet cable to your raspberry.

Open a command shell on the raspberry.

The description below assumes that the homeplug modem is connected to the ethernet interface eth0. If on your setup you are using an different interface, replace the "eth0" in the commands by the appropriate interface name.

Find the PLC adaptor

    pi@RPi3D:~ $ int6klist -ieth0 -v

This shows the software version and the mac address.

Read the configuration from the PLC adaptor and write it to a file. Use the MAC address which was found out above.

    pi@RPi3D:~ $ plctool -ieth0 -p original.pib  98:48:27:5A:3C:E6
    eth0 98:48:27:5A:3C:E6 Read Module from Memory

Patch the configuration file (see https://github.com/qca/open-plc-utils/blob/master/docbook/ch05s15.html). For each side (pev (vehicle) and evse (charger)) there is a special configuration.

For the pev side:

    pi@RPi3D:~ $ cp original.pib pev.pib
    pi@RPi3D:~ $ setpib pev.pib 74 hfid "PEV"
    pi@RPi3D:~ $ setpib pev.pib F4 byte 1
    pi@RPi3D:~ $ setpib pev.pib 1653 byte 1
    pi@RPi3D:~ $ setpib pev.pib 1C98 long 10240 long 102400

For the evse side:

    pi@RPi3D:~ $ cp original.pib evse.pib
    pi@RPi3D:~ $ setpib evse.pib 74 hfid "EVSE"
    pi@RPi3D:~ $ setpib evse.pib F4 byte 2
    pi@RPi3D:~ $ setpib evse.pib 1653 byte 2
    pi@RPi3D:~ $ setpib evse.pib 1C98 long 10240 long 102400

Write the configuration file to the PLC adaptor. Use the pev.pib or evse.pib depending on your goal. Use the MAC address which you found out above.

    pi@RPi3D:~ $ plctool -ieth0 -P pev.pib  98:48:27:5A:3C:E6
    eth0 98:48:27:5A:3C:E6 Start Module Write Session
    eth0 98:48:27:5A:3C:E6 Flash pev.pib
    ...
    eth0 98:48:27:5A:3C:E6 Close Session
    eth0 98:48:27:5A:3C:E6 Reset Device
    eth0 98:48:27:5A:3C:E6 Resetting ...

The open-plc-utils contain the programs evse and pev, which can be used for try-out of the functionality, using two PLC adaptors.

Installation / Preconditions on PC side

Usage on Windows10

See Windows installation manual

Usage on Raspberry

See Raspberry installation manual

Usage on Microcontrollers

This python project is NOT intended for use on microcontrollers like ESP32 or STM32. But there are variants ported to C:

Example flow

This chapter describes the start of a charging session, considering all layers. The checkpoint numbers can be used as reference in code and in the log files. (Todo: Only a few checkpoint numbers are referenced in the code. Adding more is work-in-progress.)

Precondition: On charger side, there is a homeplugGP-capable device present, which is configured as CentralCoordinator.

Detailled investigation about the normal end of the charging session

From Ioniq trace (https://raw.githubusercontent.com/uhi22/Ioniq28Investigations/main/CCM_ChargeControlModule_PLC_CCS/ccm_spi_ioniq_compleo_full_charge_sequence_ended_on_charger.txt.pcap.decoded.txt)

ISO

Combined together

Test results on real-world chargers

See charger_test_results.md

Testing And Simulation On Desk

See testing_and_simulation.md

Biggest Challenges

Any idea how to enable full-transparency of the AR7420?

Other open topics

See todo.md and bug_analysis.md

FAQ

Q1: What is the minimal setup, to catch the MAC addresses in the communication between a real charger and a real car?

Q2: Is it possible to use this software, to make the car closing the relay, so that I'm able to draw energy out of the car?

Good question. This depends on how strict the car is. This first hurdle is to convince the car, to close the relay. This is done after a successful PreCharge phase. And it depends on the implementation of the car, whether it needs physically correct voltage on the inlet before closing the relay, or whether it relies on the pretended voltage in the PreChargeResponse message. With setup from EvseMode manual, the Hyundai Ioniq 2016 closes the contactors by just a simulated charging session. Discussion in https://openinverter.org/forum/viewtopic.php?t=3551, pictures here: https://openinverter.org/forum/viewtopic.php?p=55656#p55656 The second hurdle is, that the car may make a plausibilization between the expected current flow (charging) and the actually measured current flow (discharging). The car may stop the complete process, if the deviation is too high or/and too long.

However, the software will help to explore and understand the behavior of the car.

Q3: Is it possible to use this software in a car without CCS, to make it ready for CCS charging?

That's is definitely a goal, and it was reached in the meanwhile. Of course, two aspects need to be considered:

Q4: Do I need to go to a public charger to test my Pev integration?

For testing the communication at home, the pyPlc supports both sides of the CCS, the car and the charger. Have a look to testing_and_simulation.md

Q5: What can be the reason, that the charger reports a failed cable check?

In the cable check phase, the charger checks the following things:

  1. CP/PE lines. The charger expects "State C", this means, the car must connect a diode and two resistors between the CP and the PE. This shall result in PWM levels of -12V and +6V. The charger measures these level, and will complain with CableCheck=Failed if it detects a mismatch. Some potential root causes for failed checks are:
    • CP is not connected at all.
    • Diode is missing or has wrong polarity.
    • Diode is too slow to handle the 1kHz/5%PWM.
    • Wrong resistor values chosen or too high tolerance of the resistors
    • Connection between circuit ground and PE missing
    • too high saturation voltage of the switch transistor
    • wrong coupling network between the CP/PE and the PLC modem transformator. This may disturb the PWM levels, due to low-pass-filtering or it may inject too much power from the PLC modem.
    • Software not configured to use the correct output path for the StateC switching
  2. Isolation of the DC path. It is recommended to use two contactors, one for each DC lines, to avoid asymmetrical results in the isolation measurements.
  3. PP line: Some chargers (e.g. some of the Tesla Superchargers) are checking the voltage between the PP line and PE. The "official" recommendation seems to be to use on car side a pull-up of 330 ohm to 5V, and perhaps 3k pulldown to ground. Discussed here: https://openinverter.org/forum/viewtopic.php?p=67464#p67464 However, many chargers (e.g. alpitronics) seem not to care for the PP at all.

Q6: How to connect the PLC modem to the CP and PE?

This is explained in the EvseMode manual. The coupling is the same in EvseMode and PevMode. EvseMode.md FAQ Question 8

Q7: The pyPLC seems to create json data by processing the hexadecimal data of receive data array, how does it do this?

The byte stream which is transferred via the homeplug physical layer runs to the following layers:

The json data, which is mentioned in the question, is the output of the EXI decoder. The pyPLC uses the following approach for the exi decoder:

Credits

Thanks to catphish to start the investigations regarding the homeplug modems and publishing them on OpenInverter forum. Thanks to johu for the OpenInverter forum, and for the first video of the early experiments, the beaglebone integration and CHAdeMO integration. Thanks to CCSknowitall for clarifying tricky details. Thanks to celeron55 for the large number of test drives to various public chargers, and for improving the software. Thanks for helpful discussions to Pete9008, peternooy, tom91, asavage and all which I forgot to mention. Thanks to arpiecodes, ArendJanKramer, fluppie and co from the SmartEvse project for the contributions. Thanks to all patreons.

Alternatives / Other projects

There are other projects around CCS charging. It's worth a look to the state and progress there.

SwitchEV

EVEREST

SmartEVSE

References