{"id":49645430,"url":"https://github.com/markoceri/leapconnect","last_synced_at":"2026-05-06T00:02:14.131Z","repository":{"id":355856321,"uuid":"1221164753","full_name":"markoceri/leapconnect","owner":"markoceri","description":"Web application to control your leapmotor vehicle","archived":false,"fork":false,"pushed_at":"2026-05-05T15:48:27.000Z","size":1372,"stargazers_count":10,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-05T16:30:09.005Z","etag":null,"topics":["api","c10","homeassistant","leapmotor","t03"],"latest_commit_sha":null,"homepage":"","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markoceri.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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-25T20:50:49.000Z","updated_at":"2026-05-05T15:48:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/markoceri/leapconnect","commit_stats":null,"previous_names":["markoceri/leapconnect"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/markoceri/leapconnect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markoceri%2Fleapconnect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markoceri%2Fleapconnect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markoceri%2Fleapconnect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markoceri%2Fleapconnect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markoceri","download_url":"https://codeload.github.com/markoceri/leapconnect/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markoceri%2Fleapconnect/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32672682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["api","c10","homeassistant","leapmotor","t03"],"created_at":"2026-05-06T00:01:26.476Z","updated_at":"2026-05-06T00:02:14.123Z","avatar_url":"https://github.com/markoceri.png","language":"Vue","funding_links":["https://ko-fi.com/markoceri"],"categories":[],"sub_categories":[],"readme":"# LeapConnect\n\n[![CI](https://img.shields.io/github/actions/workflow/status/markoceri/leapconnect/ci.yml?label=CI\u0026logo=github)](https://github.com/markoceri/leapconnect/actions/workflows/ci.yml)\n[![GitHub Container Registry](https://img.shields.io/badge/ghcr.io-leapconnect-blue?logo=docker)](https://ghcr.io/markoceri/leapconnect)\n[![License](https://img.shields.io/github/license/markoceri/leapconnect)](https://github.com/markoceri/leapconnect/blob/main/LICENSE)\n[![Version](https://img.shields.io/github/v/tag/markoceri/leapconnect?label=version)](https://github.com/markoceri/leapconnect/releases)\n[![Python](https://img.shields.io/badge/python-3.12+-blue?logo=python\u0026logoColor=white)](https://www.python.org/)\n[![FastAPI](https://img.shields.io/badge/FastAPI-0.115+-009688?logo=fastapi\u0026logoColor=white)](https://fastapi.tiangolo.com/)\n[![Vue.js](https://img.shields.io/badge/Vue.js-3-4FC08D?logo=vue.js\u0026logoColor=white)](https://vuejs.org/)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![GitHub Stars](https://img.shields.io/github/stars/markoceri/leapconnect?style=flat\u0026logo=github)](https://github.com/markoceri/leapconnect/stargazers)\n[![GitHub Issues](https://img.shields.io/github/issues/markoceri/leapconnect)](https://github.com/markoceri/leapconnect/issues)\n[![Ko-fi](https://img.shields.io/badge/Ko--fi-Support%20me-FF5E5B?logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/markoceri)\n\nWeb dashboard for monitoring and controlling Leapmotor vehicles via the [leapmotor-api](https://github.com/markoceri/leapmotor-api) Python client.\n\n## Features\n\n- **Live vehicle status**: Battery, range, speed, odometer, temperature, lock status and more\n- **Remote controls**: Lock/unlock, trunk, windows, sunshade, climate (A/C, quick cool/heat, defrost), battery preheat, find car\n- **Charge limit**: Adjustable charge limit slider\n- **Vehicle details**: Doors, windows, tire pressure, climate, connectivity, ignition\n- **Location**: OpenStreetMap embedded view with coordinates\n- **Mileage \u0026 energy**: Delivery history, total mileage\n- **Car picture**: Dinamic image reflecting lock status, doors, windows, sunshade, and lights\n- **Raw data viewer**: Full JSON inspection for debugging\n- **Multi-vehicle**: Tab switching for accounts with multiple vehicles\n- **Home Assistant integration**: Optional MQTT export of all vehicle data for smart home\n- **Local history recording**: Optional SQLite database to track vehicle data over time.\n\n## Screenshots\n\n| Login | Dashboard | Details |\n|:---:|:---:|:---:|\n| [![Login](docs/screenshots/login.png)](docs/screenshots/login.png) | [![Dashboard](docs/screenshots/dashboard.png)](docs/screenshots/dashboard.png) | [![Details](docs/screenshots/details.png)](docs/screenshots/details.png) |\n\n| History | Messages | Settings |\n|:---:|:---:|:---:|\n| [![History](docs/screenshots/history.png)](docs/screenshots/history.png) | [![Messages](docs/screenshots/messages.png)](docs/screenshots/messages.png) | [![Settings](docs/screenshots/settings.png)](docs/screenshots/settings.png) |\n\n## Tested Vehicles\n\n| Model | Status |\n|-------|--------|\n| T03 | ✅ Tested |\n| C10 | 🟡 Should work (same cloud API) |\n| B10 | 🟡 Should work (same cloud API) |\n| B05 | 🟡 Should work (same cloud API) |\n\n## Requirements\n\n- Docker \u0026 Docker Compose (for production)\n- [uv](https://docs.astral.sh/uv/) (for local development)\n- Leapmotor app certificate files (`.pem`) — [download here](https://github.com/markoceri/leapmotor-certs/archive/refs/tags/v1.0.0.zip)\n- A valid Leapmotor account\n\n\u003e **⚠️ Strongly recommended:** Create a separate Leapmotor account and share your vehicle with it, rather than using your primary account. This way, if anything goes wrong (e.g. account suspension), your main account remains unaffected.\n\n## Quick Start (Docker)\n\n### Using the pre-built image\n\n```bash\ndocker pull ghcr.io/markoceri/leapconnect:latest\n```\n\nCreate a `docker-compose.yml`:\n\n```yaml\nservices:\n  generate-certs:\n    image: alpine:latest\n    entrypoint: /bin/sh\n    command:\n      - -c\n      - |\n        if [ -f /certs/traefik.crt ] \u0026\u0026 [ -f /certs/traefik.key ]; then\n          echo \"Certificates already exist, skipping.\"\n          exit 0\n        fi\n        apk add --no-cache openssl\n        SAN=\"DNS:localhost,IP:127.0.0.1\"\n        for ip in $$(hostname -I 2\u003e/dev/null); do SAN=\"$$SAN,IP:$$ip\"; done\n        openssl req -x509 -nodes -days 3650 \\\n          -newkey rsa:2048 \\\n          -keyout /certs/traefik.key \\\n          -out /certs/traefik.crt \\\n          -subj \"/CN=leapmotor-webapp\" \\\n          -addext \"subjectAltName=$$SAN\"\n    volumes:\n      - ./traefik/certs:/certs\n    network_mode: host\n\n  traefik:\n    image: traefik:latest\n    depends_on:\n      generate-certs:\n        condition: service_completed_successfully\n    command:\n      - \"--providers.docker=true\"\n      - \"--providers.docker.exposedbydefault=false\"\n      - \"--entrypoints.web.address=:80\"\n      - \"--entrypoints.websecure.address=:443\"\n      - \"--entrypoints.web.http.redirections.entrypoint.to=websecure\"\n      - \"--entrypoints.web.http.redirections.entrypoint.scheme=https\"\n      - \"--providers.file.filename=/etc/traefik/dynamic.yml\"\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n      - ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro\n      - ./traefik/certs:/certs:ro\n    restart: unless-stopped\n\n  app:\n    image: ghcr.io/markoceri/leapconnect:latest\n    environment:\n      - HISTORY_DB_PATH=/app/data/history.db\n      - DATA_DIR=/app/data\n    volumes:\n      - ./data:/app/data\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.leapmotor.rule=PathPrefix(`/`)\"\n      - \"traefik.http.routers.leapmotor.entrypoints=websecure\"\n      - \"traefik.http.routers.leapmotor.tls=true\"\n      - \"traefik.http.services.leapmotor.loadbalancer.server.port=8099\"\n    restart: unless-stopped\n```\n\n```bash\ndocker compose up -d\n```\n\nThe app will be available at **https://localhost**.\n\n### Building from source\n\n```bash\ngit clone https://github.com/markoceri/leapconnect\ncd leapconnect\ndocker compose up -d --build\n```\n\nThe app is available at **https://localhost**.\n\nTraefik handles reverse proxying with HTTPS on port 443 and automatic HTTP→HTTPS redirect on port 80. The app container runs internally on port 8099.\n\nVehicle history data is persisted in a Docker volume (`app-data`).\n\n### HTTPS \u0026 Certificates\n\nThe Docker Compose setup includes automatic TLS certificate generation. On first `docker compose up`, a one-shot init container generates a self-signed certificate with all local IP addresses in the SAN (Subject Alternative Name), so you can access the app via `https://\u003cserver-ip\u003e` without certificate errors.\n\n- Certificates are stored in `traefik/certs/` (git-ignored)\n- If certificates already exist, the init container skips generation\n- To regenerate (e.g. after an IP change), delete the old certificates and restart:\n\n```bash\nrm traefik/certs/traefik.crt traefik/certs/traefik.key\ndocker compose up -d\n```\n\nAlternatively, you can use the standalone script to regenerate certificates with custom IPs or hostnames:\n\n```bash\nrm traefik/certs/traefik.crt traefik/certs/traefik.key\n./generate-traefik-certs.sh                     # auto-detect local IPs\n./generate-traefik-certs.sh 192.168.1.100       # add extra IP\n./generate-traefik-certs.sh myhost.local        # add extra hostname\n```\n\n## Development\n\n### Install uv\n\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\nSee [uv installation docs](https://docs.astral.sh/uv/getting-started/installation/) for other methods (Homebrew, Windows, pipx).\n\n### Backend\n\n```bash\nuv sync\nuv run pre-commit install \u0026\u0026 uv run pre-commit install --hook-type pre-push\nuv run uvicorn main:app --host 0.0.0.0 --port 8099 --reload\n```\n\nThe API runs at **http://localhost:8099**.\n\n### Tests\n\n```bash\nuv run pytest\n```\n\n### Code Quality\n\nPre-commit hooks run automatically:\n\n- **On commit**: trailing whitespace, end-of-file fix, YAML/TOML/JSON validation, ruff lint + format\n- **On push**: full pytest suite\n\nTo run all checks manually:\n\n```bash\nuv run pre-commit run --all-files\n```\n\n### Frontend\n\n```bash\ncd frontend\nnpm install\nnpm run dev\n```\n\nThe Vue dev server runs at **http://localhost:5173** and proxies `/api` calls to the backend.\n\n### Production build (manual)\n\n```bash\ncd frontend\nnpm run build\n```\n\nThis outputs to `frontend/dist/`. The FastAPI backend will automatically serve the built SPA.\n\n### Versioning\n\nThe project uses [bump-my-version](https://github.com/callowayproject/bump-my-version) to manage versions across `pyproject.toml` and `frontend/package.json`.\n\n```bash\nuv run bump-my-version bump patch   # 0.1.0 → 0.1.1 (bugfix)\nuv run bump-my-version bump minor   # 0.1.0 → 0.2.0 (new feature)\nuv run bump-my-version bump major   # 0.1.0 → 1.0.0 (breaking change)\n```\n\nEach command updates the version in both files, creates a commit, and tags it `vX.Y.Z`.\n\n**Release workflow:**\n\n1. Commit all changes\n2. Update `CHANGELOG.md` (move entries from `[Unreleased]` to a new version section)\n3. `uv run bump-my-version bump patch|minor|major`\n4. `git push --follow-tags`\n\n## Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `APP_CERT_PATH` | Yes | Path to the app certificate PEM file |\n| `APP_KEY_PATH` | Yes | Path to the app key PEM file |\n| `ACCOUNT_P12_PASSWORD` | No | P12 password (usually auto-derived from login) |\n| `HISTORY_DB_PATH` | No | SQLite database path (default: `/app/data/history.db`) |\n\n## Login\n\nYou will need:\n- **Email \u0026 Password**: Your Leapmotor account credentials\n- **Vehicle PIN** (optional): Required for remote control actions (lock, unlock, climate, etc.)\n\n## Disclaimer\n\n**This is NOT an official Leapmotor product.**\n\nLeapConnect is an independent, community-driven project with no affiliation to Leapmotor International or its subsidiaries. It interacts with Leapmotor's cloud services through unofficial, reverse-engineered APIs.\n\nBy using this software you acknowledge that:\n\n- You use LeapConnect **entirely at your own risk**.\n- The author(s) accept **no responsibility** for any consequences, including but not limited to account suspension or ban by Leapmotor.\n- Vehicle commands are sent over unofficial channels — **use remote controls with caution**.\n- The project may stop working at any time if Leapmotor changes its APIs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkoceri%2Fleapconnect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkoceri%2Fleapconnect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkoceri%2Fleapconnect/lists"}