Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

evsim

The general idea for this project is to calculate routes that stop at charge stations as needed for EVs to complete long trips in mainland North America. Currently, the start and end points must be charge stations, and user inputted coordinates are snapped to the nearest charge stations before any calculations are done. After this, the route which minimizes total drive time is found and the EV's battery level is simulated. All backend code is written in Python.

Logic Implementation

Data for this project is retrieved from 2 places.

Routing an EV trip that is longer than the EV's range involves stopping at 1 or more charge stations during the trip to recharge the EV's battery. To limit API calls needed when routing an EV trip, a "charge network" is initially created as a local offline cache of possible routes. More specifically, a charge network is a weighted graph where the vertices are charge stations and the edges are possible legs between charge stations weighted by drive time.

Clustering

To limit the complexity of the charge network without drastically changing its functionality, charge stations are clustered into groups contained within a certain diameter2 and then replaced by each group's most central charge station. This is implemented recursively using a divisive hierarchical clustering tree.

Initial Charge Network (n=3606) Clustered Charge Network (n=942)
initial charge network image with 3606 charge stations clustered charge network image with 942 charge stations
Clusters in Initial Charge Network Zoomed Clustered Charge Network Zoomed
zoomed in initial charge network image with color coded clusters zoomed in clustered charge network image with evenly distributed charge stations

Possible Legs

A possible leg is defined as a leg which has a road distance less than the max supported EV range of the charge network3. To initially populate the charge network with all possible legs, an API call must be made for each leg to compare road distance to the max supported EV range of the charge network. Using great circle distance between two charge stations as a heuristic makes the number of API calls needed feasible; an API call is only needed if the great circle distance is less than the max supported EV range of the charge network since the road distance is certainly greater than the great circle distance.

Completed Charge Network
completed charge network image

Routing

Given that the charge network represents all possible legs for the EV, routing from one charge station to another simplifies to the single-pair shortest path problem. This is solved using the A* search algorithm with great circle distance heuristic implemented using a fringe priority queue and hash set for constant time membership checking at the expense of space complexity.

Simulating Battery

After a route has been found, the start battery of the EV is initialized based on the user input. Battery depletion is simulated linearly with road distance. Battery charging is simulated following a non-linear regression of current battery technology where the charge rate diminishes as the battery approaches fully charged4. With this in mind, at each charge station, the EV is only simulated to charge just enough to make it to the next charge station as charging more than that will be at an unoptimal charge rate.

Web App Implementation

The Python logic in the backend retrieves user input and serves output to the web app using the Flask framework, along with Jinja interpolated HTML, and static JavaScript. Flask is also used to store user input as a cookie on form submission. Three Google Maps API endpoints are used. All 3 are rate limited via "quotas". The Directions endpoint is only called on the backend and is further restricted by IP. The Places endpoint is also only called on the backend, but since it is billed by token sessions, the "quota" rate limit is not helpful. Thus, an SQLite database is used for token and session logic to enforce request limits via the API wrapper routes of this Flask app. It is also restricted by IP. Finally, the JavaScript Maps endpoint is called by the frontend and is both stored in unicode code points to avoid it being scraped from GitHub and restricted by HTTP referrer.

Deployment

This project is deployed on an OCI Ampere A1 Flex VM running Oracle Linux 85. The Flask app is run in a Python 3.12 venv using the WSGI HTTP server Gunicorn which is run behind Nginx configured as a HTTP reverse proxy server (recommended by Gunicorn). SSL certificates are created and renewed using Certbot in its own venv.

The following commands were used (with sudo redacted for readability).

Installs

dnf install git python3.12 nginx

Oracle Linux 8 Quirks

firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload

setsebool -P httpd_can_network_connect 1

Nginx

cat > /etc/nginx/conf.d/main.conf << "EOF"
server {
    server_name www.evsim.ca evsim.ca;
    location / {
        proxy_pass http://127.0.0.1:5000;
    }
}
EOF

systemctl start nginx

Certbot

python3.12 -m venv /opt/certbot/
/opt/certbot/bin/pip install certbot certbot-nginx
ln -s /opt/certbot/bin/certbot /usr/bin/certbot
certbot --nginx

echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null

Gunicorn

git clone https://github.com/skrukwa/evsim.git
cd evsim/src
python3.12 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
gunicorn --bind 127.0.0.1:5000 app:app

Footnotes

  1. Currently only charge stations with at least 4 DC fast chargers located in mainland NA are used.

  2. Currently this is 60km.

  3. Currently this is 700km.

  4. Currently this is the regression function used.

  5. This used to be AWS EC2 but my free trial ran out 🙁.

About

shortest path finding and EV battery simulation

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages