kevinkwee/Mi-Fitness-Sync
GitHub: kevinkwee/Mi-Fitness-Sync
非官方 Python CLI,通过逆向 Mi Fitness 云端 API 拉取锻炼数据并导出为标准运动格式,解决官方 Strava 同步失败的问题。
Stars: 0 | Forks: 0
# Mi Fitness 同步
一个用于访问 Mi Fitness 健身数据和手动同步未能上传至 Strava 的活动的非官方 Python CLI。
## 为什么会有这个项目
Mi Fitness 是小米可穿戴设备使用的 Android 应用。当手表记录了一次锻炼后,数据会通过蓝牙/BLE同步到手机,然后上传到用户小米账号下的 Mi Fitness 云端。
Mi Fitness 官方支持诸如 Strava 的第三方集成。但在实际使用中,有些锻炼活动即使已经显示在 Mi Fitness 中,有时也不会上传到 Strava。
我创建这个项目,是因为我希望能有一种方法,手动同步那些在 Mi Fitness 中记录但未能成功上传到 Strava 的锻炼。
## 适用场景
这主要在以下情况对你有用:
1. 确认你的锻炼数据确实存在于 Mi Fitness 云存储中
2. 在 Mi Fitness 未能将活动推送到 Strava 时,检查近期的活动
3. 亲自拉取活动数据,而不必等待官方同步生效
4. 将锻炼数据导出为 GPX、TCX 或 FIT 格式,以便进行手动备份和重新上传
## 项目结构
代码库的设置包含:
1. 一个 `src/` 目录布局
2. 用于项目元数据的 `pyproject.toml` 文件
3. 名为 `mi_fitness_sync` 的 Python 包
大部分实际代码位于 `src/mi_fitness_sync` 目录下。
## 安装
推荐使用 Python 3.12+。
以可编辑模式安装:
```
python -m pip install -e .
```
然后通过以下命令运行:
```
python -m mi_fitness_sync --help
```
如果你暂时不想安装,仓库根目录下还提供了一个简单的封装脚本:
```
python main.py --help
```
## 快速开始
1. 使用你的 Xiaomi / Mi 账号进行身份验证
2. 验证已保存的认证状态
3. 列出 Mi Fitness 云端中近期的锻炼活动
4. 获取某一次锻炼的标准化活动详情
5. 将锻炼活动导出为 GPX、TCX 或 FIT 格式
示例:
```
python -m mi_fitness_sync login --email you@example.com --password your-password
python -m mi_fitness_sync auth-status
python -m mi_fitness_sync list-activities --limit 10
python -m mi_fitness_sync activity-detail sid:key:1717200000 --json
python -m mi_fitness_sync export-activity sid:key:1717200000 --format gpx --output exports/run.gpx
```
如果你想改用封装脚本:
```
python main.py login --email you@example.com --password your-password
python main.py auth-status
python main.py list-activities --limit 10
python main.py activity-detail sid:key:1717200000 --json
python main.py export-activity sid:key:1717200000 --format fit --output exports/run.fit
```
## 命令
### `login`
登录 Xiaomi Passport 以使用 Mi Fitness 服务,并在本地保存认证状态。
示例:
```
python -m mi_fitness_sync login --email you@example.com --password your-password
```
相关标志:
1. `--state-path` 用于覆盖默认的认证状态文件路径
### `auth-status`
显示当前已保存的 Mi Fitness 认证状态。
示例:
```
python -m mi_fitness_sync auth-status
python -m mi_fitness_sync auth-status --json
```
### `list-activities`
使用已保存的认证状态,从 Mi Fitness 云端列出锻炼活动。
示例:
```
python -m mi_fitness_sync list-activities --limit 10
python -m mi_fitness_sync list-activities --since 2024-01-01 --json
python -m mi_fitness_sync list-activities --since 1717200000 --until 1719800000 --limit 50
python -m mi_fitness_sync list-activities --since 2026-03-20 --country-code ID
```
相关标志:
1. `--since` 和 `--until` 接受 Unix 时间戳或 ISO-8601 格式的时间戳
2. `--limit` 控制返回的活动数量
3. `--category` 传递 Mi Fitness 的类别过滤器(如果你已知类别字符串)
4. `--country-code` 使用双字母国家代码(例如 `ID`、`GB` 或 `US`)覆盖活动路由;CLI 会将其映射为 Android 应用所使用的 Mi Fitness 区域
5. `--json` 将解析后的活动列表输出为 JSON 格式
如果省略 `--country-code`,CLI 将保持现有的 Mi Fitness 自动区域检测行为。
### `activity-detail`
获取由 `list-activities` 返回的某个活动 ID 的更丰富的标准化详情 payload。
示例:
```
python -m mi_fitness_sync activity-detail sid:key:1717200000
python -m mi_fitness_sync activity-detail sid:key:1717200000 --country-code ID --json
```
相关标志:
1. `activity_id` 必须来自 `list-activities` 输出的 `activity_id` 字段
2. `--country-code` 使用与 `list-activities` 相同的区域覆盖行为
3. `--json` 打印标准化详情模型,包括解析后的轨迹点和采样数据
详情查找行为:
1. 当 Mi Fitness 提供更丰富的锻炼 JSON payload 时,CLI 仍然会优先使用它。
2. 它现在还会探测经验证的 `healthapp/service/gen_download_url` 控制面路径,并在原始详情输出中包含任何发现的 FDS 元数据。
3. 如果 Mi Fitness 未返回更丰富的 JSON blob,CLI 会回退到带有时间戳的健身时间线样本,以便 TCX 和 FIT 导出仍能在尽力而为的基础上工作。
### `export-activity`
使用标准化详情 payload 将单个活动导出为标准文件格式。
示例:
```
python -m mi_fitness_sync export-activity sid:key:1717200000 --format gpx --output exports/run.gpx
python -m mi_fitness_sync export-activity sid:key:1717200000 --format tcx --output exports/run.tcx.gz --gzip
python -m mi_fitness_sync export-activity sid:key:1717200000 --format fit --output exports/run.fit
```
相关标志:
1. `--format` 必须为 `gpx`、`tcx` 或 `fit` 之一
2. `--output` 为目标文件路径
3. `--gzip` 在写入之前使用 gzip 压缩生成的 payload
4. `--country-code` 使用与 `list-activities` 相同的区域覆盖行为
导出行为:
1. GPX 要求 Mi Fitness 详情 payload 中包含 GPS 轨迹点
2. 当缺少完整 GPS 数据时,TCX 和 FIT 可以回退到带有时间戳的运动样本
3. FIT 生成是尽力而为的,仅包含 Mi Fitness 源 payload 中存在的字段
### `logout`
删除已保存的本地认证状态。
示例:
```
python -m mi_fitness_sync logout
```
## 本地认证存储
默认情况下,认证状态存储在用户主目录下的 `.mi-fitness-strava-sync/auth.json` 文件中。
你可以通过以下方式覆盖该位置:
1. `--state-path`
2. 环境变量 `MI_FITNESS_AUTH_PATH`
## 限制
1. 这是一个非官方项目,不隶属于 Xiaomi、Mi Fitness 或 Strava。
2. Xiaomi 登录流程的某些部分是通过应用行为和反编译代码拼凑出来的。
3. Xiaomi 可能随时更改端点、cookie、签名或响应格式。
4. 某些账户可能需要验证码、通知批准或第二步验证流程,这些在此并未完全自动化。
5. 详情检索目前依赖于 Android 应用使用的原始 `huami_sport_record` payload 结构;Xiaomi 可能会在不通知的情况下更改该格式。
6. 某些账户似乎暴露了锻炼的 FDS 下载 URL 元数据,但实际上并未保留相应的云端对象,因此实时 GPS/blob 检索仍不完善。
7. 对于 Mi Fitness 未暴露 GPS 轨迹点的锻炼,无法进行 GPX 导出。
8. TCX 和 FIT 可以回退到带有时间戳的时间线样本,但该回退方案不包含路线几何信息。
9. FIT 导出是尽力而为的,当 Mi Fitness 没有为更完整的活动文件提供足够的源数据时,可能会省略某些字段。
## 安全提示
1. CLI 目前直接在命令行中接收账户凭据。
2. 根据你的环境,Shell 历史记录可能会保留这些值。
3. 认证状态文件包含敏感的会话数据,应当妥善保护。
如果你在共享机器上使用此工具,请像对待凭据一样对待本地的认证状态。
## 许可证
该项目基于 MIT 许可证授权。详情请参阅 [LICENSE](LICENSE) 文件。
标签:Amazfit, API对接, DNS解析, FIT, GPX, Mi Fitness, Python 3.12, Python CLI, Strava, TCX, Zepp, 云存储, 备份工具, 小米手环, 小米账号, 开源项目, 数据同步, 数据导出, 文档结构分析, 智能手表, 穿戴设备, 第三方集成, 网络调试, 自动化, 运动数据, 运动记录, 运动轨迹, 逆向工具