{"id":48237280,"url":"https://github.com/robeertm/ev-charge-tracker","last_synced_at":"2026-05-10T15:18:58.496Z","repository":{"id":349186055,"uuid":"1201384995","full_name":"robeertm/ev-charge-tracker","owner":"robeertm","description":"Self-hosted EV charge tracker with vehicle API integration (Kia, Hyundai, Tesla, VW group, Renault, Polestar +more). Dashboard, PDF reports, ENTSO-E CO2, multi-language. Flask + SQLite.","archived":false,"fork":false,"pushed_at":"2026-04-20T07:31:10.000Z","size":8283,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T07:37:36.357Z","etag":null,"topics":["co2-tracking","dashboard","electric-vehicle","entsoe","ev-charging","ev-tracker","flask","home-server","hyundai","kia","photovoltaic","polestar","python","renault","self-hosted","sqlite","tesla","volkswagen"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robeertm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-04T15:55:22.000Z","updated_at":"2026-04-20T07:31:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/robeertm/ev-charge-tracker","commit_stats":null,"previous_names":["robeertm/ev-charge-tracker"],"tags_count":127,"template":false,"template_full_name":null,"purl":"pkg:github/robeertm/ev-charge-tracker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robeertm%2Fev-charge-tracker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robeertm%2Fev-charge-tracker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robeertm%2Fev-charge-tracker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robeertm%2Fev-charge-tracker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robeertm","download_url":"https://codeload.github.com/robeertm/ev-charge-tracker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robeertm%2Fev-charge-tracker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32130776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T08:34:57.708Z","status":"ssl_error","status_checked_at":"2026-04-22T08:34:55.583Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["co2-tracking","dashboard","electric-vehicle","entsoe","ev-charging","ev-tracker","flask","home-server","hyundai","kia","photovoltaic","polestar","python","renault","self-hosted","sqlite","tesla","volkswagen"],"created_at":"2026-04-04T20:03:19.758Z","updated_at":"2026-05-10T15:18:58.485Z","avatar_url":"https://github.com/robeertm.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EV Charge Tracker\n\n\u003e **Self-hosted dashboard for tracking your electric vehicle charges** — costs, kWh, CO2, recuperation, charging losses, and live vehicle status. Multi-vehicle / fleet support, connects to 14 EV brands via API. Available in 6 languages.\n\n[![Latest Release](https://img.shields.io/github/v/release/robeertm/ev-charge-tracker)](https://github.com/robeertm/ev-charge-tracker/releases)\n[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n![Python](https://img.shields.io/badge/python-3.10%2B-blue)\n![Self-Hosted](https://img.shields.io/badge/self--hosted-yes-green)\n\nBuilt for EV owners who want **full control over their charging data** — runs locally on your laptop, NAS, or Raspberry Pi. No cloud, no tracking, no subscription. Your data stays on your machine.\n\n---\n\n## Screenshots\n\n### Dashboard\n![Dashboard](docs/screenshots/dashboard.png)\n*Monthly cost chart, AC/DC/PV breakdown, yearly summary — everything on one page.*\n\n### Dark Mode\n![Dark Mode](docs/screenshots/dashboard-dark.png)\n*Day/night toggle synced across all tabs.*\n\n### Live Vehicle Status\n![Vehicle](docs/screenshots/vehicle.png) ![Vehicle Dark](docs/screenshots/vehicle-dark.png)\n*Battery, range, odometer, 12V, SoH, tyre pressure, doors — pulled directly from the car via Vehicle API. Cached or live-refresh on demand.*\n\n### Fahrtenbuch (Trip Log)\n![Trips](docs/screenshots/trips.png)\n*Auto-built from GPS pings: trips, totals, commute distance, map of all stops, smart-sync every 10 min during waking hours.*\n\n### New Charge — Start/Stop tracking\n![New Charge](docs/screenshots/input.png)\n*AC / DC / **PV** button row, auto-fills SoC, odometer, and CO2 from the live grid. Start/Stop triggers a force-refresh from the car.*\n\n### History\n![History](docs/screenshots/history.png)\n*Filter by year and charge type, inline edit km, CSV export.*\n\n### Maintenance Log\n![Maintenance](docs/screenshots/maintenance.png)\n*Inspections, tyres, parts — with cost tracking and next-service reminders by date or odometer.*\n\n### Live Log Viewer\n![Logs](docs/screenshots/logs.png)\n*In-app log window: auto-refresh, level filter, text search, optional HTTP access logging, CSV download.*\n\n### Settings — Vehicle API\n![Settings](docs/screenshots/settings.png)\n*Vehicle API auto-sync with configurable smart window (default 06:00 – 22:00, every 10 min). 14 supported brands, GHG quota, ENTSO-E, HTTPS, PV system — all configurable from the UI.*\n\n---\n\n## Why this app?\n\n| Problem | Solution |\n|---|---|\n| Apps from your carmaker only show last 30-90 days | **Lifetime tracking** in your own database |\n| No privacy / data sold to third parties | **100% local** — SQLite file on your machine |\n| Cant compare AC vs DC vs PV cost \u0026 CO2 | Built-in **AC/DC/PV split** with separate tariffs |\n| GHG quota payouts not tracked | **THG quota** card deducts payouts from total cost |\n| Manual logging is tedious | **Vehicle API** auto-fills SoC, odometer, charging status |\n| ENTSO-E grid CO2 not integrated | **Hourly CO2 intensity** auto-fetched, missing values backfilled |\n\n---\n\n## Features\n\n### Multi-vehicle / fleet (v3.0+)\n- **Track any number of cars in one install** — every charge, sync, parking event, trip and maintenance record is anchored to one specific vehicle for life. Sold a car? Archive it; its lifetime kWh / km / cost stays in fleet aggregates\n- **Navbar fleet picker** — flip between \"whole fleet\" view and a single vehicle from any page; dashboards, history, trips, maintenance, report and the new-charge form all respect the selection\n- **Per-vehicle hardware** — battery kWh, SoH baseline, battery production CO₂, max-AC kW, recuperation rate, fossil-CO₂/km, color, icon\n- **Per-vehicle API credentials** — every car has its own brand / user / password / pin / region / VIN; the daily API quota counter (200/day for Kia/Hyundai), smart-sync window, force-refresh queue and SDK trip-info reconcile are all per-vehicle so a 5-car fleet doesn't share a single quota\n- **Per-vehicle THG-Quote** — German EV emissions certificate payouts are bound to the right car; the year-end reminder warns only when a non-archived vehicle is missing the previous year's payout\n- **Setup wizard step 3** — first-install flow lets you register multiple vehicles in one shot before the app opens\n\n### Tracking\n- **Mobile-friendly input form** — quickly log charges from your phone, with Cancel button, native operator `\u003cselect\u003e` (datalist-free so iOS Safari works), and optional GPS-captured station location\n- **\"My Location\" uses the car's last GPS, not the phone** — pulls from the most recent `VehicleSync` row with coordinates so the station position reflects where the charge actually happened, even if you're back home when logging it. Phone GPS remains a secondary option\n- **Operator price auto-fill** — configure per-operator `€/kWh` prices in Settings; picking an operator on the charge form auto-fills the price field (only while you haven't typed anything, so manual overrides are never lost)\n- **Start/Stop charge tracking** — force-refresh from vehicle, auto-fill date/time/SoC/odometer, auto-stop when charge limit reached\n- **Live vehicle status widget** on dashboard — SoC, range, odometer, doors, tires, climate, SoH, location\n- **Vehicle history** — every sync persists SoC, range, odometer, 12V, SoH, recuperation, 30-day consumption, GPS. Stored only when a tracked value changes (compact, audit-friendly history)\n- **Raw data viewer** (`/vehicle/raw`) — pretty-prints the full API dump for every sync, per brand, for debugging unusual SoH/range values\n- **History** with filtering, inline km editing, CSV export\n- **Full edit form** — every stored charge field (location, operator, coordinates, map picker) editable after the fact via `/edit/\u003cid\u003e`\n\n### Driving log / Fahrtenbuch\n- **Auto-detected parking events** — every vehicle sync hooks into a parking-event log; \u003e100 m means \"moved\", new event opened, previous closed with arrival/departure odometer + SoC\n- **Home / Work / Favorites** — pick locations on a Leaflet/OpenStreetMap card in Settings; events are auto-classified (home / work / favorite / other) within a 200 m radius. Favorites are inline-editable (rename, reposition via map, delete) with per-row action buttons\n- **Trips page** at `/trips` — KPI cards (count, km, drive time, commute km), marker-cluster map, full table with from/to/km/duration/avg-speed/SoC\n- **Full trip editor** — click the pencil on any trip row to open a two-column modal (Start / End) with every `ParkingEvent` field: label, favorite name, address, arrival/departure times, odometer and SoC at arrival/departure, coordinates. A shared Leaflet map below has draggable markers (blue = start, red = end) plus a \"pick on map\" button per side. Derived values (trip km, SoC used, recuperation) recompute automatically from the stored fields\n- **7-day safety gate** on trip edits — entries older than 7 days require an explicit confirmation checkbox; server-enforced via 409 response, so hand-crafted requests can't bypass it\n- **CSV + GPX export** — `/api/trips/export.csv` for the tax advisor, `/api/trips/export.gpx` for Google Earth / Komoot / OsmAnd\n- **Smart sync mode** — runs cached by default but auto-upgrades to a force-refresh when GPS is older than 6 h and the car is not charging, so the Fahrtenbuch stays current without burning the daily API quota\n- **Backfill** — replays existing vehicle syncs through the parking hook to retroactively rebuild the driving log\n\n### Maintenance log / Wartungs-Logbuch\n- **`/maintenance` page** — track inspections, tires, brakes, wipers, 12V battery, cabin filter, MOT/TUEV with date, odometer, cost and notes\n- **Smart reminders** — entries can have a `next_due_km` and/or `next_due_date`; due-soon / overdue banner with sensible defaults per item type (e.g. inspection = 12 months / 30 000 km)\n\n### Analytics\n- **Dashboard** with KPI cards, Chart.js visualizations, and 7 vehicle-history mini time-series (SoC, range, odometer, 12V, SoH, recuperation, consumption)\n- **Click-to-fullscreen on every plot** — each mini-chart is its own framed card with a fullscreen icon; click opens a Bootstrap `modal-fullscreen` with a larger version (thicker line, more axis ticks, grid, data-point circles). Time-range selector in the card header: 24h / 7d / 30d / 90d / 1y / all. Chosen range persists per-user in `AppConfig`\n- **Last-known GPS** — the dashboard location card walks the vehicle-history series backwards to find the most recent GPS-bearing sync, so the map still renders under Kia/Hyundai cached mode where the latest sync typically has no coordinates\n- **Range calculator** card — uses live SoC + battery capacity + 30-day consumption + outdoor temperature (Open-Meteo at home location), with a temperature penalty curve\n- **Weather correlation** chart — bar (kWh/month) + line (avg outdoor degC) showing exactly why winter is more expensive\n- **Highlights / fun facts** — cheapest/most expensive charge, biggest single charge, longest trip, fastest trip, longest park\n- **PDF Report** — multi-page report with 10 charts, KPI overview, monthly/yearly/AC-DC-PV tables, vehicle-history time-series, Fahrtenbuch (last 80 trips with home\u003c-\u003ework km for the German Pendlerpauschale), Wartungs-Logbuch, highlights page\n- **CO2 break-even chart** — cumulative savings vs. battery production CO2 (well-to-wheel)\n- **Recuperation stats** — total energy recovered, extra km, recuperation charge cycles\n- **Cost \u0026 consumption per 100km** — net of GHG quota payouts\n- **THG quota reminder** — banner Jan 1 - Mar 31 if no quota is logged for the previous year\n\n### Integrations\n- **14 vehicle brands** via API (see table below) — auto-fetch SoC, odometer, charging status\n- **Brand feature matrix** in Settings — 10-item green/yellow/red grid per brand (SoC, GPS, 12V, SoH, recuperation, 30-day consumption, doors, climate, tires, live status). No more \"wait, why isn't my car showing X\" surprises.\n- **ENTSO-E integration** — fetch hourly CO2 grid intensity for Germany, auto-backfill missing values\n- **Open-Meteo** — daily mean temperatures for the range calculator and weather correlation, with DB cache (no key, no rate limits)\n- **Nominatim reverse geocoding** — for street addresses on parking events and charge locations, with permanent DB cache and ToS-compliant rate limiter\n- **CSV import with live preview** — upload your Google Sheet or exported CSV in Settings, get a dry-run preview showing detected delimiter, column mapping (per-column dropdown to correct misdetections), per-row action badges (`new` / `update` / `duplicate` / `empty` / `error`), and an error list with line numbers. Only when you hit \"Import\" does the data actually land in the DB. Automatic dedup by (date, hour, kWh) with 0.1 kWh tolerance\n- **PV charging support** — third charge type with auto-calculated CO2 from PV system specs\n- **Operator price directory** — Settings has an editable table of charging operators (19 built-ins + your customs) with per-operator `€/kWh`. Stored as JSON in `AppConfig` and consulted by the charge-entry form to auto-fill the price\n\n### Security / HTTPS\n- **Self-signed certificate** auto-generation via `cryptography` (or `openssl` CLI fallback). SAN entries cover `localhost`, `127.0.0.1`, and the LAN IP, so the same cert works on desktop AND smartphone\n- **Three modes** in Settings: `off` (HTTP), `auto` (self-signed), `custom` (paths to your own Let's Encrypt cert)\n- **Cert metadata viewer** + downloadable `.crt` to install on your phone via Profile (kills browser warnings permanently)\n- HTTPS is required for the Geolocation API on smartphones — the auto mode gets you there in two clicks\n- **Auto-hide** of the HTTPS card in Settings when the request comes from a Tailscale peer (100.64.0.0/10), since the VPN already provides transport encryption — less clutter for VM deployments\n\n### Web-UI login (optional password gate)\n- **Opt-in** front gate with username/password, shown before any route when enabled in Settings → Zugangsschutz\n- **Werkzeug password hashing** (bcrypt-compatible), credentials in `AppConfig`\n- **Flask signed session cookie** with a per-install random 32-byte secret that's generated on first boot and persisted — sessions survive restarts and updates\n- **Use case**: when the Tailscale share link is known to other devices but you still want a password in front of your charge data\n\n### First-run Setup Wizard (VM deployments)\n- **Browser-based wizard** that appears on first access to a freshly provisioned VM (triggered by a `/srv/ev-data/.setup_pending` marker)\n- **Two steps**: LUKS passphrase change (`sudo cryptsetup luksChangeKey` under the hood) and SSH login password change (`sudo chpasswd`)\n- **Resume-safe**: progress is tracked in a state file so a mid-wizard reload doesn't reset the user\n- **Result**: an end user can take ownership of a VM without touching a terminal — no SSH, no `cryptsetup`, no manpages\n\n### Self-hosting / updates\n- **In-app updater** — \"Update available\" button in Settings actually rolls out the new release on your machine (download zip, stage, detached helper swaps files, pip install, restart). No `git pull`, no terminal.\n- **systemd-aware**: under systemd the file swap is done inline in the running process and the supervisor restarts the service; outside systemd the legacy detached-helper flow is used\n- **Automatic rollback on a broken update** — before every swap, a backup of the files that would be overwritten is written to `updates/backup_pre_v\u003cOLD\u003e/` along with a `UPDATE_PENDING.json` marker. On each boot, a pre-flight state machine checks the marker: three failed boots in a row (or a port-7654 bind timeout within 60 seconds of launch) trigger an automatic restore of the previous version plus a `LAST_ROLLBACK.json` note for the UI. Works under any supervisor that restarts on crash. `data/`, `venv/`, `.git/`, `logs/`, `updates/` are never touched by the backup/restore.\n- **Dashboard update banner** — a visible banner appears on the dashboard when a newer release is available; clicking jumps directly to `Settings → #updaterCard`. If the last update auto-rolled back, a second banner explains which versions were involved and offers a one-click dismiss (`DELETE /api/update/last-rollback`). Update-check response is cached in `sessionStorage` for 30 minutes so page-hopping doesn't hit the GitHub API on every view.\n- **Restart button** in Settings for applying HTTPS changes or new certs\n- **API rate limiter** — tracks daily API calls (Kia EU: 190/200 limit), counter on dashboard\n\n### VM deployment (multi-user rollout)\n- **Templated VM image** for DS1621+ / Synology VMM and other hypervisors: Debian base with Xvfb + x11vnc + noVNC for the Kia token capture flow, XRDP for occasional maintenance, UFW restricted to the `tailscale0` interface, systemd unit with `Restart=always` and `ConditionPathExists=/srv/ev-data/app/venv/bin/python` so it skips cleanly while the LUKS volume is locked\n- **`ev-provision` script** on each clone — auto-detects the data disk, formats LUKS with a temporary passphrase, registers with Tailscale via a pre-auth key, sets up sudoers entries for the wizard, enables UFW, prints handover info\n- **`ev-unlock` helper** — one command after VM boot, opens the LUKS volume, mounts it, starts the app\n- **End-to-end flow**: admin clones the template → runs `ev-provision` once → shares the VM via Tailscale device sharing → user runs through the browser wizard → done\n\n### UX\n- **Dark/Light mode** — toggle in navbar, synced across all tabs via localStorage\n- **6 languages** — German, English, French, Spanish, Italian, Dutch (~800 translated strings per locale)\n\n---\n\n## Quick Start\n\n```bash\n# Clone\ngit clone https://github.com/robeertm/ev-charge-tracker.git\ncd ev-charge-tracker\n\n# Quick start (recommended)\n# macOS:   double-click start.command\n# Linux:   ./start.sh\n# Windows: double-click start.bat\n\n# Or manually:\npip install -r requirements.txt\npython app.py\n```\n\nOpen `http://localhost:7654` in your browser.\nFrom your phone (same network): `http://\u003cyour-pc-ip\u003e:7654`\n\n---\n\n## Vehicle API — Supported Brands\n\nConnect your car to automatically fetch SoC, odometer, and charging status. All packages installable directly from Settings UI (no terminal needed).\n\n| Brand | Package | Auth |\n|-------|---------|------|\n| **Kia** | `hyundai-kia-connect-api` | Refresh-Token (OAuth via Selenium) |\n| **Hyundai** | `hyundai-kia-connect-api` | Refresh-Token (OAuth via Selenium) |\n| **Volkswagen** | `carconnectivity` + connector | Username / Password |\n| **Skoda** | `carconnectivity` + connector | Username / Password |\n| **Seat** | `carconnectivity` + connector | Username / Password |\n| **Cupra** | `carconnectivity` + connector | Username / Password |\n| **Audi** | `carconnectivity` + connector | Username / Password |\n| **Tesla** | `teslapy` | OAuth Refresh-Token |\n| **Renault** | `renault-api` | Username / Password |\n| **Dacia** | `renault-api` | Username / Password |\n| **Polestar** | `pypolestar` | Username / Password |\n| **MG (SAIC)** | `saic-ismart-client-ng` | Username / Password |\n| **Smart #1/#3** | `pySmartHashtag` | Username / Password |\n| **Porsche** | `pyporscheconnectapi` | Username / Password |\n\nAfter installing, configure credentials in Settings \u003e Vehicle API. Optional background sync polls your vehicle at a configurable interval (1-12h).\n\n**Kia/Hyundai note:** Password login is blocked by reCAPTCHA. Use the \"Fetch Token\" button in settings — opens Chrome with mobile user-agent for the OAuth flow. Token is valid for ~1 year.\n\n---\n\n## Import from Google Sheet\n\n**Via Web UI (recommended):**\n1. Open your Google Sheet \u003e File \u003e Download \u003e CSV\n2. In the app: Settings \u003e Database \u003e CSV Import \u003e Upload\n\n**Via CLI:**\n```bash\npython import_gsheet.py downloaded_file.csv\n```\n\nThe importer handles German number format (comma as decimal separator) and various date formats. Missing CO2 values are automatically fetched from ENTSO-E in the background after import.\n\n---\n\n## ENTSO-E Setup\n\n1. Register at [transparency.entsoe.eu](https://transparency.entsoe.eu/)\n2. Request an API token via email\n3. Enter the token in Settings within the app\n4. Optionally select the charging hour for hour-specific CO2 data\n\n---\n\n## Vehicle Settings\n\nConfigure in Settings \u003e Vehicle:\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| Battery capacity | 64 kWh | Battery size for cycle \u0026 loss calculation |\n| Max AC power | -- | Max AC charging power |\n| Battery production CO2 | 100 kg/kWh | For break-even calculation (MY2021) |\n| ICE CO2 WTW | 164 g/km | Well-to-wheel comparison (DE average) |\n| Recuperation | 0.086 kWh/km | Energy recovered per km |\n\n### PV System (Settings \u003e PV)\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| System size | -- | kWp of your PV system |\n| Annual yield | 950 kWh/kWp | Annual yield per kWp (DE average) |\n| Lifetime | 25 years | Expected system lifetime |\n| Manufacturing CO2 | 1000 kg/kWp | Production CO2 incl. transport \u0026 installation |\n| PV electricity price | 0.00 EUR/kWh | Self-consumption cost |\n\n---\n\n## Languages\n\nSwitchable from Settings \u003e Language:\n\n- Deutsch\n- English\n- Francais\n- Espanol\n- Italiano\n- Nederlands\n\n~800 translated strings per language. Falls back to German if a key is missing. New languages can be added by dropping a `\u003clang\u003e.json` file into `translations/`.\n\n---\n\n## Tech Stack\n\n- **Backend:** Python 3.10+, Flask, SQLAlchemy, SQLite\n- **Frontend:** Bootstrap 5.3 (with dark mode), Chart.js\n- **PDF:** matplotlib + fpdf2\n- **Data:** ENTSO-E Transparency Platform API\n- **Vehicle APIs:** hyundai-kia-connect-api, teslapy, renault-api, pypolestar, saic-ismart-client-ng, pySmartHashtag, pyporscheconnectapi, carconnectivity\n\n---\n\n## Contributing\n\nPull requests welcome! Areas where help is appreciated:\n- More vehicle API connectors\n- Additional language translations (just add `translations/\u003clang\u003e.json`)\n- Charts and analytics ideas\n- Mobile UX improvements\n\n---\n\n## License\n\nRobert Manuwald 2021-2026\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobeertm%2Fev-charge-tracker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobeertm%2Fev-charge-tracker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobeertm%2Fev-charge-tracker/lists"}