GodrezJr2/j5-ev-dashboard

GitHub: GodrezJr2/j5-ev-dashboard

一款自托管的移动端 PWA 仪表盘,通过逆向 CarLinko 遥测 API 为 Jaecoo J5 EV 车主提供原厂 App 缺失的电池、充电、能效与行程规划等详细数据展示。

Stars: 0 | Forks: 0

# J5 EV 仪表板 —— 专为 Jaecoo J5 EV 设计的自托管车联网仪表板 **English** · [Bahasa Indonesia](README.id.md) 一款简洁的、移动优先的 PWA,可显示您的车辆已上报的**真实**数据 —— 电池、续航里程、总里程、充电会话、能效、轮胎状态、12 V 健康状况、行程日志、累计成本、长途出行充电规划器,以及交互式的 SPKLU(电动汽车充电桩)地图。 它的诞生是因为原厂的 CarLinko 应用隐藏了大部分数据(轮胎状态仅显示 “正常/异常”,没有行程汇总,没有充电成本历史记录,也没有公路旅行规划器)。 这里的一切数据均派生自您的车辆**已经**发送至其自有云端的真实数据 —— 本 项目仅读取您自己的账户并将其合理地呈现出来。 ## 截图 | 仪表板 | 充电 | | :---: | :---: | | ![主仪表板 —— 电池、续航、轮胎、能效、洞察](https://static.pigsec.cn/wp-content/uploads/repos/cas/65/659500f906cab8ef1a62d8b6b03c335b2b8ec7a10442f728cebc86ec2d650011.png) | ![充电标签页 —— 电池保养、充电统计、充电目标规划器](https://static.pigsec.cn/wp-content/uploads/repos/cas/42/42a14a2098edafdc7f5cbc35101630782fd702e547eb257dbd8d78787b74d9e8.png) | | **行程规划器** | **SPKLU 地图** | | ![长途规划器 —— 路线、沿途带有连接器类型和到达电量的充电停靠点](https://raw.githubusercontent.com/GodrezJr2/j5-ev-dashboard/main/docs/screenshots/trip-planner.png) | ![交互式 SPKLU 地图 —— 标记点、实时可用状态、路线指引](https://static.pigsec.cn/wp-content/uploads/repos/cas/94/94e84b8a3d34e69b9ed2448ef879b40ea94baecc4242de27c54aa11961432d1c.png) | *车牌和 VIN 默认已打码(通过隐私切换按钮控制)。图中为浅色主题 —— 内置深色主题以及 EN/ID 语言切换功能。* ## ⚠️ 法律与道德声明 —— 请先阅读本节内容 这是一个**个人互操作性/逆向工程**项目,旨在访问**您自己的车辆和您自己的账户**。本项目仅供教育和个人使用。 - **仅对您拥有的账户和汽车使用本工具。** 请勿访问任何其他人的数据。 - 本项目与**私有的、无文档的供应商 API** 进行通信。本项目**不提供任何保证**,如果供应商更改了其后端,它可能随时失效。本项目**不附属于、不受认可、也不受** Jaecoo、Chery 或 CarLinko **的支持**。 - **本项目不附带任何机密信息。** 请求签名密钥、设备身份数据块、token、VIN、 车牌、车辆 ID 和设备序列号都**不**包含在这个仓库中 —— 您需要在被 gitignore 忽略的 `creds.json` 文件中自行提供(参见[安装说明](#setup))。 - **请勿将其作为公共/托管的多用户服务运行。** 这样做意味着存储他人的凭证(这些凭证可用于解锁/控制他们的车辆),这几乎肯定会违反供应商的服务条款。预期的部署方式是**每位车主各自运行一个实例**,自托管且保持私密(例如通过 Tailscale 访问)。请参阅[转向多用户](#going-multi-user)。 - 设计时即为只读模式。**未**实现车辆的远程控制功能。 如果您不接受上述内容,请勿使用本工具。 ## 功能 - **实时状态** —— 电池 %、续航里程、总里程、12 V 电源、在线/驻车/充电/行驶状态, 从实时 WebSocket 拉取并缓存在 SQLite 中。 - **充电功能** —— 自动检测的充电会话(输入电池组的电量 kWh、电表计费的电量 kWh、成本), 充电曲线图,每周/每月充电次数统计,以及配备真实 SPKLU 费率的“充电至 X %”规划器。制动回收电量的波动已被过滤,不会污染充电历史记录。 - **能效与行程** —— 包含严谨数据验证的单次行程和滚动 kWh/100 km 能耗计算,终身 kWh / 成本 / km 统计,并根据印尼真实的燃油价格计算相比汽油车节省的开支。 - **长途规划器** —— 设定起点/终点,获取沿途的充电停靠点规划,预留安全裕度确保到达(类似 ABRP 风格),并提供来自 Google 的真实连接器类型 / kW / 实时可用状态。 - **SPKLU 地图** —— 浏览交互式地图,点击充电桩查看连接器、实时可用状态和 路线指引(类似 PLN-Mobile 风格),数据来源于 Google Places。 - **电池保养、保养倒计时、轮胎视图、隐私切换、深色模式、EN/ID 国际化。** 请参阅 [PRODUCT.md](PRODUCT.md) 了解产品理念,参阅 [DESIGN.md](DESIGN.md) 了解视觉系统规范。 ## 架构 ``` Car TCU ──(cellular)──> CarLinko cloud ──┐ │ WebSocket (token auth, no signing) — telemetry blob tools/logger.py ◀───────────────────────┘ decodes + stores every frame to carlinko.db │ (auth.py auto-refreshes the token on expiry) ▼ carlinko.db (SQLite) │ ▼ tools/server.py ── /api/summary, /api/trip, /api/spklu ──▶ web/ PWA (vanilla JS, Leaflet) (stdlib http.server) + Google Places (optional) served over Tailscale ``` - **无框架、无构建步骤。** 后端使用 Python 标准库;前端是手写的 HTML/CSS/JS,并包含两个外部引入的库(Leaflet,slot-text)。支持自托管且对离线使用友好。 - **遥测数据是一个 73 字节的数据块。** 字段偏移量是通过驾驶汽车并观察哪些字节发生了变化来还原的(电池电量 = 第 28 字节,续航里程 = 第 29–30 字节 大端序,总里程 = 第 18–20 字节 大端序,…)。 请参阅 [docs/api-map.md](docs/api-map.md)。 ## 准确度 充电数据分析已根据车主真实的 PLN Mobile 收据进行了校准: | 会话 | 仪表板 | 收据 | 匹配度 | | ------------------ | -------------------- | -------------------- | ------- | | 58 → 100 % | 28.9 kWh / Rp 73,491 | 28.94 kWh / Rp 73,521 | 99.9 % | | 35 → 80 % | 29.1 kWh / Rp 73,981 | 29.23 kWh / Rp 74,273 | 99.6 % | 直流充电效率被建模为依赖 SoC(充电至 100 % 的损耗比充至 80 % 更大), 并根据两份收据进行了校准。可用电池组容量 ≈ 58.9 kWh。 充电规划器会预测您在电表端实际需要支付的金额,已通过真实的 PLN Mobile SPKLU 收据验证: | 应用的充电规划器 | 真实的 PLN Mobile 收据 | | :---: | :---: | | ![充电规划器预估](https://static.pigsec.cn/wp-content/uploads/repos/cas/57/5731b7fa24f827da9534edcfb270cd0096a84b1c242279a54edb07f6b58b58c3.png) | ![PLN Mobile SPKLU 收据](https://static.pigsec.cn/wp-content/uploads/repos/cas/c9/c99dd011cd38d06b7fb630a9c96eabceaf9b12cf3d276ceca79316a7720a5ddc.png) | 应用估算需要在电表端购买 **58.2 kWh**,价格为 **Rp 2,540/kWh**;收据显示 **实际交付了 57.34 kWh**,适用的同样是 **Rp 2,540/kWh** 的总价 —— 每 kWh 的价格完全准确,且电量落在约 ~1.5 % 的误差范围内(收据显示的会话由于未完全充满而提前结束)。退款金额的计算也对得上:购买了 Rp 152,448,使用了 Rp 145,694。 ## 安装说明 ### 前置条件 - Python 3.10+,`pip install requests websocket-client` - 一个 CarLinko 账户 + 与之绑定的汽车 - (可选)用于行程规划器 / SPKLU 地图的 Google Maps API key - 一种能拦截一次您自己的应用流量的方法(见下文) ### 首次抓取(唯一的手动步骤) 供应商 API 会对每个请求进行签名,并使用设备数据块固定身份。您需要**从您自己的应用中,一次性提取以下两个**值: 1. **`sign_key`** —— 应用用于签名请求的 HMAC key。它存在于应用二进制文件中; 通过反编译 `libapp.so` 来还原它(本仓库使用了 [Blutter](https://github.com/worawit/blutter);偏移量记录在 [docs/decompiled/secure_request_utils.dart](docs/decompiled/secure_request_utils.dart) 中)。 2. **`v_data`** —— 每次请求都会发送的恒定 base64 设备身份数据块。通过 MITM 拦截您自己的应用来抓取它(Flutter 会忽略系统代理和信任库,因此请使用 [reFlutter](https://github.com/Impact-I/reFlutter) + 模拟器配合 `-http-proxy` + mitmproxy / HTTP Toolkit)。同样的抓包过程也会揭示您的 `vehicle_id` 和 `device_sn`。 ### 快速开始 —— Docker(推荐) ``` docker compose run --rm web python setup.py # interactive: email, password, sign_key, v_data docker compose up -d # dashboard on http://localhost:8088 ``` `setup.py` 会登录并**自动检测您的汽车**(从 API 获取车辆 ID、设备 SN、VIN、车牌、型号)—— 您无需手动填写这些信息。所有需要持久化的内容(凭证、token、数据库)都保存在 `./data` 中。 ### 快速开始 —— Python(无 Docker) ``` pip install requests websocket-client cd tools python setup.py # interactive config + login + auto-detect car python logger.py --adaptive # record telemetry (fast when awake, slow when parked) python server.py 8088 # dashboard at http://:8088 ``` 不想使用辅助脚本?可以执行 `cp creds.example.json tools/creds.json && chmod 600 tools/creds.json` 并手动填写内容。`creds.json` 和 `token.txt` 已被 gitignore 忽略 —— 切勿提交它们。 为了实现常驻运行,请安装提供的 systemd 服务单元 ([carlinko-logger.service](tools/carlinko-logger.service), [carlinko-web.service](tools/carlinko-web.service)),并通过 Tailscale 访问仪表板,这样可以在不向互联网暴露任何端口的情况下保持私密性。 ### `creds.json` 参考 | key | 是否必填 | 说明 | | --- | --- | --- | | `email`, `password` | ✅ | 您的 CarLinko 登录信息(通过 TLS 明文传输;仅在本地存储) | | `region` | | API 区域,默认为 `sea` | | `sign_key` | ✅ | 请求签名 HMAC key(从您的应用中提取) | | `v_data` | ✅ | 常量设备身份数据块(抓取一次即可) | | `vehicle_id`, `device_sn` | 自动 | 您的车辆 ID + 设备序列号 —— **`setup.py` 会为您自动填充** | | `vehicle` | 自动 | `{车牌, 型号, vin}` —— 自动检测;UI 默认隐藏车牌和 VIN | | `battery_kwh`, `wltp_kwh_100`, `tariff_idr` | | 针对特定型号/本地的覆盖值(默认为 J5 参数) | | `gmaps_key` | | Google Maps key —— 启用行程规划器 + SPKLU 地图(否则回退至 OSM) | ## 转向多用户 这是**有意设计为每个实例单租户模式**。允许其他车主使用它的最干净的方法是**让他们各自运行自己的实例**并使用各自的 `creds.json` —— 而不是托管一个保存所有人凭证的单一服务。针对不同的车型,可以覆盖 `battery_kwh` / `wltp_kwh_100` / `tariff_idr`,并且车辆名称/VIN/车牌均来自 `creds.json`,因此该应用已经可以针对不同的车辆进行适配。 ## 项目布局 - `tools/` —— Python 后端(`server.py`, `logger.py`, `auth.py`)+ 逆向工程实用工具 - `web/` —— PWA(单一的 `index.html` + 引入的 `leaflet.*`, `slot-text.js`) - `docs/` —— API 映射表和反编译签名说明(机密信息已打码) - `PRODUCT.md`, `DESIGN.md` —— 产品 + 视觉设计说明 ## License [MIT](LICENSE)。与 Jaecoo、Chery 或 CarLinko 无关。商标归其各自所有者所有。
标签:API逆向, IPv6支持, PWA, 个人项目, 后端开发, 多模态安全, 数据可视化, 物联网, 电动车监控, 请求拦截, 逆向工具