PyPLC
Overview
Charging via CCS DC Fast Charge requires Powerline Communication (PLC). The TP-Link TL-PA4010 (discontinued, but widely available used) is an inexpensive home PLC unit that is designed to use a residence's mains wiring (power lines) as a communication medium for ethernet. It can be repurposed to be used as a CCS EV Communications Controller (EVCC)[1]. In its new role, it communicates via PLC over the CP line to the EVSE. It can be reliable when powered by a range of low DC voltages, 12v down to under 5v. Additional resources have been compiled by uhi22[2].
TL-PA4010
The TL-PA4010 utilizes the Qualcomm Atheros QCA7420 PLC comm IC. Examples can be purchased via eBay etc. for well under USD$20 (Apr2023). Variants include a single-PCB version, and a version with a mains pass-through which uses two PCBs. Both variants utilize the same PLC IC, the AR7420, and both adapt well for CCS.
Setting up a CCS Charging Station
Starting point: [3]
Hardware
Modifying a TP Link TL-PA4010 firmware and settings [4]
Software
Setting up a BeagleBone for pyPLC including CAN commincation
There are a number of platforms that pyPLC will run on, for example also on a Raspberry Pi or any other linux computer. The BeagleBone is quite cheap and versatile. Make sure you grab a version with an Ethernet port like the BB green or BB black.
Then here are the steps to get up and running:
- Upgrade to the latest debian image (at the time of writing that is Debian 10.3 IoT): https://beagleboard.org/latest-images
- Plug it into your USB port. You will now be able to reach the board under two IP addresses 192.168.6.2 and 192.168.7.2
- Use SSH to connect:
ssh debian@192.168.6.2
- Make sure you can connect to the internet. Easiest way to achieve it is plugging the Ethernet port into your local router. You can also route traffic via the computer that the beaglebone is plugged into (see below)
- Update the APT package list:
sudo apt update
- Get the so called EXI converter OpenV2Gx:
git clone https://github.com/uhi22/OpenV2Gx
- Build it:
cd OpenV2Gx/Release && make
(this will take rather long!) - Get pyPLC:
git clone https://github.com/uhi22/pyPLC/
- Install some necessary packages:
sudo apt install python3-pypcap python3-serial python3-can
- Edit /etc/connman/main.conf and add eth0 to its blacklist by adding it to the line
NetworkInterfaceBlacklist=SoftAp0,usb0,usb1,eth0
- When using CAN, enable the CAN0 "cape" by editing /boot/uEnv.txt and adding the line
uboot_overlay_addr0=/lib/firmware/BB-CAN0-00A0.dtbo
then reboot - Bring up eth0 and (if needed) CAN:
sudo ip link set eth0 up && sudo ip link set can0 up type can restart-ms 100 bitrate 500000
- Run pyPLC:
cd pyPLC && sudo python3 pevNoGui.py
Routing traffic via the USB connected computer
On your computer:
Linux:
This is only needed for the setup phase.
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo iptables -A FORWARD -j ACCEPT
Windows:
TBD
On the Beaglebone:
sudo route add default gw 192.168.6.1
sudo tee /etc/resolv.conf <<<"nameserver 192.168.xxx.1" #address of your local router here
pyPLC MQTT interface
pyPLC supports various interfaces to the physical world in hardwareInterface.py. Rather than extending it to match your hardware setup consider using MQTT to get values in and out of pyPLC.
To enable MQTT for all signals set
digital_output_device=mqtt analog_input_device=mqtt charge_parameter_backend=mqtt
in pyPlc.ini . Also check that mqtt_broker etc. are correct
These are the current definitions. The example config defines "pyPlc/" as base topic, that's what we assume here.
Topic | Meaning in PEV mode | Meaning in EVSE mode |
---|---|---|
pyPlc/battery_voltage | [input] Present battery voltage | none |
pyPlc/target_voltage | [input] Target battery voltage | [output] Target voltage requested from vehicle. Momentary battery voltage in state "PreCharge" |
pyPlc/target_current | [input] Charge current request to EVSE | [output] current requested from vehicle |
pyPlc/soc | [input] SoC to be reported to EVSE | [output] SoC reported by vehicle |
pyPlc/inlet_voltage | [input] physical inlet voltage | none |
pyPlc/enabled | none | [input] user stop request |
pyPlc/fsm_state | pyPLC state | |
pyPlc/cpstate | [output] command for CP state switch, "B" or "C" | none |
pyPlc/relay_request | [output] command for port contactor, "on" or "off" | none |
pyPlc/lock_request | [output] command for port lock, "lock" or "unlock" | none |
pyPlc/charger_max_voltage | [output] maximum voltage capability received from EVSE | [input] Maximum power supply voltage |
pyPlc/charger_max_current | [output] maximum current capability received from EVSE | [input] Maximum power supply current |
pyPlc/charger_voltage | [output] present voltage at charger | [input] present power supply voltage |
pyPlc/charger_current | [output] present current at charger | [input] present power supply current |