Skip to content

ZeppBridge 0.10.0

Choose a tag to compare

@github-actions github-actions released this 25 Aug 12:59
· 94 commits to main since this release

新增身体状态与训练状态两个页面,心率区间支持三种算法,并接入跑步功率与跑姿。

新增:身体状态页(/body

  • 八张趋势卡:恢复、压力、血氧、夜间血氧 ODI、HRV (SDNN)、HRV (RMSSD)、呼吸率、静息心率。
  • 每张卡支持 7 天 / 1 个月 / 6 个月切换。数据早已在本机库里,这一版只是把它们呈现出来,不需要重新联网。
  • 压力、血氧、HRV、呼吸率在折线后面画出当日实测区间的阴影;当天没测出区间的,不画零宽阴影。
  • 每张卡都写明覆盖度,例如「30 天里有 12 天记录」。没有记录的那几天曲线直接断开,不插值也不补 0。
  • 某个范围内只有 1 天数据时不画图,直接说「画不出趋势」——一个读数是数值,不是趋势。

新增:训练状态页(/training

  • VO₂max、训练负荷、PAI 三张趋势卡。
  • 乳酸阈值卡:心率与配速双轴,配速轴反向,让「更快」朝上。
  • 运动负荷平衡卡:7 天负荷、28 天周均、急慢比三条线。急慢比 = 7 天负荷之和 ÷(28 天负荷之和 ÷ 4);28 天窗口覆盖不足 21 天时不给比值,曲线在那里断开——是没算,不是等于零。
  • 急慢比与导出里的 training_load_balance 现在共用同一个函数,界面和文件不可能给出不同的数字。
  • 6 个月这一档不是装饰:VO₂max 与乳酸阈值一年只测几次,30 天窗口会把库里已有的数据显示成空。

新增:心率区间,三种算法,不预设默认

  • 支持最大心率区间、储备心率区间、乳酸阈值区间三种算法。
  • 五个基准全部取自本机实测,各自标注出处与测量日期:max(workouts.max_hr)daily_metrics.device_max_hrdaily_metrics.device_resting_hr、近 30 天 avg(daily_metrics.resting_hr)daily_metrics.lactate_threshold_hr
  • 不预设默认,也不替你挑基准。 选择器初始为空;导出里 selected_modelnull 时列出全部可算的组合,每一项 selected 都是 false
  • 不使用 220−年龄 之类的公式估算。
  • 区间百分比与向下取整不是照抄来的:运动摘要里带着手表自己的边界(heart_range)与 heartrate_setting_type。本账号 heartrate_setting_type = 3、边界 113/141/154/162/173/190,而 lactateThresholdHr = 175——正好是 floor(175 × 65/81/88/93/99/109%)。这组数字现在由测试守着。
  • 五个区间之外的时间单独统计为「低于 Z1」与「高于 Z5」,五个带标签的区间因此严格就是标签所说的范围。

新增:跑步功率与跑姿

workout_samples 增加五列,全部由本地已存的原始报文回填,不需要重新联网。每一项都对着同一次运动的摘要字段验证过,不是看着像就接:

字段 语义 验证方式
power_meter 跑步功率(W) 序列均值 249.3 / 231.5 对上摘要 average_power 249.0 / 231.0;最大值 326 / 303 对上 max_power
runPosture 第 1 项 触地时间(ms) 均值 263.5 对上 averageGct 263,最小值 232 对上 minGct
runPosture 第 2 项 垂直振幅(mm) 均值 88.3 对上 averageVo 88,最大值 95 对上 maxVo
runPosture 第 3 项 垂直步幅比(%) 均值 87.1 对上 avgVertStrideRatio 87;且 88 mm ÷ 1010 mm 步幅 = 8.7%,两个字段互证单位
equivPace 等效配速(秒/公里) 最小值 264 对上 bestEquivPace;按距离加权均值 355.8 对上 avgEquivPace 355
  • 运动详情页新增六项:平均功率、最大功率、平均触地时间、平均垂直振幅、垂直步幅比、最佳等效配速。
  • runPosture 的哨兵 65535255 一律转 null,不落库为 0。
  • equivPace 不是 1/speed:两者逐秒比对有三分之一的样本对不上,最佳偏移下仍有 32%–36% 偏差。它是坡度校正配速,不能拿现有 pace 顶替,也不能拿它反推速度。
  • 站着不动时设备照发等效配速读数,本账号库里出现过 51604 秒/公里(十四小时每公里)。读取路径只接受 60–3600 秒/公里,与 pace 转分钟每公里用的是同一个窗口。

改动:概览页

  • 新增「身体状态」「训练状态」两张入口卡,各带当日数值与 7 天走势。
  • 这两张卡取代了原来的训练负荷、VO₂ Max 两张小卡——同一屏不重复展示同一个数字。
  • 走势图少于两个点时不画:一个读数是数值不是趋势,画成一条平线等于宣称了没测过的稳定性。

改动:交给 AI

  • 「已选数据流」从只读列表改成真正的选择器:按活动 / 睡眠 / 身体状态 / 训练四组呈现,组标题可整组全选或全不选,单项是复选框。
  • 提示词模板只负责预填选择,不再锁定它。勾了什么,导出就是什么,摘要里的条数与体积始终描述你马上会拿到的那个文件。

修复:重放与同步抢锁

  • 解析器修订号变化后,启动时的原始报文重放会批量写库;此前落在这期间的自动同步会输掉 SQLite 写锁之争,弹出红色的「workouts 失败:本地数据库暂时不可用」。数据其实一条没丢。
  • 现在同步会主动让路,返回中性的 deferred 状态并在一分钟后自动重试,横幅是灰色而不是红色。
  • busy_timeout 从 5 秒提高到 30 秒。
  • SyncReport.outcome 因此新增 deferred

数据层与接口

  • SQLite schema 升到 user_version = 10(新增跑步功率与跑姿列)。
  • NORMALIZER_REVISION 升到 zepp-normalizer-2026-08-v14
  • 新增四个 command:get_metric_seriesget_training_balanceget_heart_rate_zonesset_heart_rate_zone_preference
  • get_metric_series 只应答白名单内的指标名,别的直接跳过,调用方写错名字不会得到一个凭空编出单位的图表。
  • 心率区间选择的四个槽位都可为 null——「还没决定」必须能存回去。
  • 设置页「你的设备能提供什么」卡片对齐设计 token,与上方「连接设备」卡片统一间距、圆角与字号。
  • Rust 测试从 98 个增加到 102 个。

文档

  • README 重写:界面一览、当前能力、下载与安装、第一次连接、隐私、许可证全部对齐现状。
  • 架构摘要补上运动 detail 字段的验证结论、心率区间三种算法的来源,以及事件接口的第四种形态(/users/me/fileInfo/events)。
  • 发版说明改为取附注标签的正文,而不是自动生成的 commit 列表。

已知未接入

以下四项都留在「未验证清单」里,没有猜测性接入:

  • Charge/insight_data — 曾被怀疑是综合能量分,已排除:同一天可以出现三条样本(insight 分别为 6 / 79 / 6)。一个日度分数不会一天出现三个值。字段语义没有对照组可验证,因此只保留原始报文。
  • Charge/stress_data — 已确认是 protobuf,解析后是四组 float32,没有一组对得上 App 显示的日均与区间。日汇总走已验证的 all_day_stress
  • 逐秒心率 — 接口确认有数据,但返回的是文件索引而不是样本,取到样本还需要下载额外域名上的文件;接入等于放宽 host 白名单,未做。
  • 2026-08-16 之后的逐条血氧 — 点测在该日停止,之后只有夜间汇总。已逐一排除文件索引接口、band_data 8 字节块、auto / real_data 子类型;剩下的方向只有抓取 App 的真实请求,而本项目禁止恢复 MITM / 用户 CA / 代理路线,因此到此为止。

升级注意

首次启动这一版时,应用会在后台重放本地已存的原始报文来回填跑步功率与跑姿。大库(1 GB 以上)约需 15 分钟,跑在后台线程,不阻塞窗口;期间的自动同步会显示灰色的「稍后自动重试」而不再报错。整个过程不需要联网。