reuhenbhalod/DayBreak

GitHub: reuhenbhalod/DayBreak

一款完全离线、零订阅的 Android 应用,将 COLMI R09 智能戒指的原始 BLE 数据转化为基于个人动态基线的睡眠、恢复和活动每日评分。

Stars: 0 | Forks: 0

# 黎明 🌅

Kotlin Jetpack Compose Android BLE Room MIT License

## 目录 - [截图](#screenshots) - [问题背景](#the-problem) - [Daybreak 的功能](#what-daybreak-does) - [三大指标](#the-three-scores) - [功能特性](#features) - [工程亮点](#engineering-highlights) - [架构](#architecture) - [入门指南](#getting-started) - [运行测试](#running-the-tests) - [项目结构](#project-layout) - [隐私](#privacy) - [免责声明](#disclaimer) - [许可证](#license) ## 截图

Home screen with the three daily scores and trends Daily steps and last night's sleep stages Blood oxygen trend and per-score contributor breakdown One-time onboarding flow

带有趋势图的三大每日指标 · 步数与睡眠阶段细分 · SpO2 及指标贡献因素 · 一次性设置流程

## 问题背景 可穿戴健康追踪确实非常有用。了解你的睡眠状况,以及今天适合“大干一场”还是“放松一下”,能够真正改变你的行为习惯。然而,市面上的主流选择却将这些洞察锁定在昂贵的硬件、按月收取的订阅费用,以及一个掌握着你生物特征数据的云端账号背后。 与此同时,COLMI R09——一款低调的智能戒指,具备光学心率、SpO2、睡眠分期和步数追踪功能——已经被开源社区完全逆向工程。传感器就在那里,数据也可以被解码。现在唯一缺失的是“最后一公里”:一款干净利落、理念清晰的应用程序,能够将原始的 BLE 数据包转化为一个一目了然的答案。 因此,我为一个真实的用户:**我爸爸**,端到端地构建了我自己的 Oura。衡量这款应用成功的标准只有一个:他每天早上瞥一眼手机,就能通过文字明白自己昨晚睡得如何,以及今天是否需要放松休息。 ## Daybreak 的功能 Daybreak 使用完全基于逆向工程的 COLMI 数据包格式从头编写的协议层,通过 Bluetooth Low Energy 直接与戒指通信。它每天会在后台自动同步几次,在设备本地计算出三个每日 0-100 的指标,并通过平实易懂的文字摘要将它们呈现在单一的主屏幕上: 所有操作均在本地运行。**无需账号。没有云端。无需订阅。该应用甚至没有申请网络权限**,因此你的心率数据在物理上绝对不可能离开你的手机。 | | Oura | Daybreak | |---|---|---| | 硬件 | 专属戒指,价格高昂 | 现成的智能戒指,搭配定制软件 | | 订阅 | 按月收费 | 永久免费 | | 数据位置 | 他们的云端 | 100% 保留在你的设备上 | | 每日指标 | 睡眠 / 准备状态 / 活动 | 睡眠 / 恢复 / 活动 | | 评分模型 | 不公开 | 开源,已在本 repo 中记录 | | 离线可用 | 部分支持 | 完全支持 | ## 三大指标 所有指标都是标准化贡献因素的加权总和,每项均根据佩戴者**自身过去 14 个晚上的动态基准**进行评分:看重趋势变化,而非单次读数。校准保护机制会在基准稳定之前抑制指标显示,因此前两周绝不会出现误导性的数字。 - 😴 **睡眠**:总睡眠时间对比基于年龄的需求、睡眠效率、深度睡眠和 REM 睡眠比例对比基准、睡眠安宁度、作息规律性以及入睡潜伏期。 - 🔋 **恢复**:前一晚的睡眠、静息心率对比基准、HRV 平衡、*恢复指数*(静息 HR 在夜间多早达到最低点),以及前一天的活动负荷。当固件不提供 HRV 时,它的权重会被重新分配给静息心率和睡眠,而不是无声地用零填充。该指标会优雅地降级,绝不产生虚假数据。 - 🏃 **活动**:步数对比个性化目标(在恢复不佳的日子里目标会自动降低)、活动时间、久坐惩罚以及活动平衡度。 一个基于规则的生成器会将这些指标及其主要驱动因素转化为一句温暖、非临床风格的句子。一个可选的**设备端 LLM 摘要生成器**(MediaPipe GenAI)可以接管这项工作,且依然完全离线。 ## 功能特性 - 📡 **零干预后台同步**:WorkManager 会安排一个有保障的早晨同步窗口并进行额外补充;补漏逻辑会在下一次成功连接时自动填补任何错过的夜晚数据。佩戴者永远不需要手动按下“同步”。 - 🛰️ **完整的 BLE 协议实现**:带校验和验证的 16 字节命令数据包、用于睡眠记录的多包“大数据”重组,以及用于心率日志、步数和 SpO2 的流式组装器。 - 🧮 **纯 Kotlin 评分引擎**:无 Android 依赖,完全经过单元测试,可移植到任何平台。 - 🏠 **单屏幕 UX**:大字体,采用带有非颜色提示的色码设计,专为年长且非技术背景的佩戴者打造。主屏幕上没有复杂的菜单或标签页。 - 📊 **洞察**:指标趋势图、昨晚的睡眠分期图、标有夜间最低心率的夜间心率曲线、活动图表,以及每个指标下各贡献因素的细分,所有这些均使用 Compose `Canvas` 绘制。 - ❤️ **按需心率**:点击即可从戒指获取实时读数。 - 🔕 **隐形失败**:戒指超出范围或同步失败时,会静默显示昨天的数据。第一天之后,永远不会再出现错误对话框。 - 📤 **本地 CSV 导出**:将你自己的数据作为文件分享;绝对不会上传任何内容。 - 🔎 **诊断屏幕**:为维护者提供同步日志和原始数值,且不会干扰佩戴者的日常使用。 ## 工程亮点 - **逆向工程的 BLE 协议,经过整洁重构。** `:protocol` 模块实现了 COLMI R0x 数据包格式(校验和 = 前 15 个字节之和的低字节)、BCD 日期编码,以及 `0xBC` 大数据特征值的分块传输,已通过 Gadgetbridge 的解析器进行验证并在真实硬件上测试通过。 - **严格的模块化架构。** `:protocol` 和 `:scoring` 是零 Android 依赖的纯 JVM Kotlin 模块。`:app` 模块通过 `RingClient` 接口将它们与 Room、WorkManager 和 Compose 连接起来,该接口具有真实的 BLE 实现和空操作测试替身。 - **以优雅降级作为设计原则。** 平价戒指硬件对其局限性非常诚实:没有温度传感器、依赖固件的 HRV、存在噪音的睡眠分期。评分模型会明确地围绕缺失的信号重新调整权重,而不是假装它们存在。 - **抵御 Android 后台限制的韧性。** 支持感知 Doze 模式的调度、开机接收器、重试和退避策略,以及作为纯逻辑进行测试的早晨同步策略。 - **跨越所有三个模块的约 30 个单元测试文件**,涵盖了数据包编码、重组边缘情况、每个指标的贡献因素计算、缺少 HRV 时的回退机制、补漏同步窗口以及摘要生成。 - **产品思维文档化。** 完整的 [产品需求文档](Daybreak_PRD.md)(包括硬件能力矩阵、评分权重、UX 原则和风险分析)均保存在本 repo 中。 ## 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ :app (Android) │ │ │ │ Compose UI Sync Data │ │ ┌────────────┐ ┌───────────────┐ ┌────────────────┐ │ │ │ Home │ │ SyncWorker │ │ Room database │ │ │ │ Insights │◄────┤ SyncScheduler ├───►│ Repository │ │ │ │ Onboarding │ │ CatchUp │ │ SettingsStore │ │ │ │ Diagnostics │ │ MorningPolicy │ │ CSV export │ │ │ └────────────┘ └───────┬───────┘ └────────────────┘ │ │ │ │ │ ┌───────▼───────┐ │ │ │ RingClient │ (BLE state machine) │ │ └───────┬───────┘ │ └─────────────────────────────┼─────────────────────────────────┘ │ ┌─────────────────────┼──────────────────────┐ │ │ │ ┌───────▼────────┐ ┌───────▼────────┐ │ BLE │ :protocol │ │ :scoring │ ▼ │ (pure Kotlin) │ │ (pure Kotlin) │ ┌─────────────┐ │ │ │ │ │ COLMI R09 │ │ Packet codec │ │ SleepScore │ │ smart ring │ │ Big-data │ │ RecoveryScore │ └─────────────┘ │ reassembly │ │ ActivityScore │ │ Sleep/HR/SpO2/ │ │ Baselines │ │ steps parsers │ │ SummaryGen │ └────────────────┘ └────────────────┘ ``` | 层级 | 技术 | |---|---| | 语言 | Kotlin 2.x, coroutines + Flow | | UI | Jetpack Compose, Material 3, 定制 `Canvas` 图表 | | 持久化 | Room (SQLite), 本地设置存储 | | 后台任务 | WorkManager + 开机接收器 + Doze 处理 | | 连接 | Android BLE, 定制 COLMI R0x 协议层 | | 设备端 AI(可选) | MediaPipe Tasks GenAI | | 构建 | Gradle 8.11 (Kotlin DSL), version catalog, KSP | ## 入门指南 ### 前置条件 - **JDK 17+**(推荐 JDK 21) - 包含 API 35 的 **Android SDK**(命令行工具或 Android Studio) - 一台运行 **Android 8.0+** 的 Android 手机 - 一枚 **COLMI R09** 智能戒指(没有它应用也能运行,只是没有数据可同步) ### 构建 ``` git clone https://github.com/reuhenbhalod/DayBreak.git cd DayBreak # 如果你的默认 JDK 不同,请将 Gradle 指向受支持的 JDK,例如在 macOS 上: export JAVA_HOME=$(/usr/libexec/java_home -v 21) ./gradlew :app:assembleDebug ``` 生成的 APK 位于 `app/build/outputs/apk/debug/`。 ### 安装与配对 ``` adb install app/build/outputs/apk/debug/app-debug.apk ``` 1. 打开 Daybreak 并完成引导流程:授予蓝牙和附近设备权限,以及电池优化豁免权限(这能让后台同步在 Doze 模式下依然保持运行)。 2. 扫描并配对戒指。只需一次,终生有效。 3. 设置佩戴者的年龄和睡眠需求。 4. 完成。随着数据的积累,各项指标将开始显示;在 14 晚的校准期结束后,将解锁完整的评分功能。 ## 运行测试 协议编解码器和整个评分模型都是纯 JVM 模块,因此测试套件无需模拟器即可快速运行: ``` ./gradlew :protocol:test :scoring:test :app:testDebugUnitTest ``` ## 项目结构 ``` DayBreak/ ├── app/ # Android app (Compose UI, Room, WorkManager, BLE client) │ └── src/main/kotlin/com/daybreak/ │ ├── ble/ # RingClient interface + real & no-op implementations │ ├── data/ # Room entities, DAOs, repository, settings │ ├── export/ # Local CSV export │ ├── summary/ # Rule-based + optional on-device LLM summarizer │ ├── sync/ # WorkManager sync, catch-up, morning policy, boot receiver │ └── ui/ # Home, Insights, Onboarding, Diagnostics, custom charts ├── protocol/ # Pure-Kotlin COLMI R0x BLE protocol layer │ └── src/main/kotlin/com/daybreak/protocol/ │ ├── Packet.kt # 16-byte packet codec + checksum │ ├── BigDataReassembler.kt # Multi-packet 0xBC payload reassembly │ └── ... # Sleep, HR-log, SpO2, and steps parsers ├── scoring/ # Pure-Kotlin scoring engine (no Android deps) │ └── src/main/kotlin/com/daybreak/scoring/ │ ├── SleepScore.kt · RecoveryScore.kt · ActivityScore.kt │ ├── Baselines.kt # Rolling personal baselines │ └── SummaryGenerator.kt # Plain-language daily summary ├── docs/screenshots/ # App screenshots used in this README └── Daybreak_PRD.md # Full product requirements document ``` ## 隐私 Daybreak 在架构设计上就是本地优先的,这并非出于策略妥协: - v1 版本**未申请任何网络权限**,因此操作系统本身就能保证不会上传任何数据。 - 没有账号,没有分析,没有遥测。 - 所有数据都存储在手机本地的 SQLite 数据库中。 - 数据离开设备的唯一途径是*你*主动导出 CSV 文件并进行分享。 ## 免责声明 Daybreak 是一个独立的、受 Oura *启发* 的项目。它不隶属于 Oura,也未获得其认可,不使用 Oura 的品牌或算法,而是实现了自己的开源评分模型。它是一款**健康辅助工具,而非医疗器械**。它显示的任何内容均不构成医疗诊断。 ## 许可证 基于 [MIT License](LICENSE) 发布。
标签:Android 应用, Jetpack Compose, Kotlin, 健康数据追踪, 智能穿戴, 本地离线, 蓝牙低功耗