From 82b794f1f0952d52f82bf2a2181edc8545f034ff Mon Sep 17 00:00:00 2001 From: Saksham Bhutani Date: Sun, 28 Jun 2026 03:52:02 -0400 Subject: [PATCH 1/5] added mkdocs --- .github/workflows/docs.yml | 78 +++++++ .gitignore | 4 + README.md | 10 +- docs/assets/logo.svg | 16 ++ docs/getting-started/android.md | 95 +++++++++ docs/getting-started/ios.md | 83 ++++++++ docs/hardware/colmi.md | 173 +++++++++++++++ docs/hardware/index.md | 246 ++++++++++++++++++++++ docs/hardware/jring.md | 132 ++++++++++++ docs/hardware/premium.md | 102 +++++++++ docs/hardware/simsonlab.md | 59 ++++++ docs/{ => images}/AI-coach-design.png | Bin docs/{ => images}/ble-interaction.png | Bin docs/{ => images}/system-architecture.png | Bin docs/{ => images}/thumbnail.png | Bin docs/index.md | 131 ++++++++++++ docs/platforms/ios-vs-android.md | 210 ++++++++++++++++++ docs/project/architecture.md | 75 +++++++ docs/project/contributing.md | 127 +++++++++++ docs/project/privacy.md | 32 +++ docs/project/roadmap.md | 89 ++++++++ docs/stylesheets/extra.css | 125 +++++++++++ mkdocs.yml | 120 +++++++++++ requirements-docs.txt | 3 + 24 files changed, 1905 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/assets/logo.svg create mode 100644 docs/getting-started/android.md create mode 100644 docs/getting-started/ios.md create mode 100644 docs/hardware/colmi.md create mode 100644 docs/hardware/index.md create mode 100644 docs/hardware/jring.md create mode 100644 docs/hardware/premium.md create mode 100644 docs/hardware/simsonlab.md rename docs/{ => images}/AI-coach-design.png (100%) rename docs/{ => images}/ble-interaction.png (100%) rename docs/{ => images}/system-architecture.png (100%) rename docs/{ => images}/thumbnail.png (100%) create mode 100644 docs/index.md create mode 100644 docs/platforms/ios-vs-android.md create mode 100644 docs/project/architecture.md create mode 100644 docs/project/contributing.md create mode 100644 docs/project/privacy.md create mode 100644 docs/project/roadmap.md create mode 100644 docs/stylesheets/extra.css create mode 100644 mkdocs.yml create mode 100644 requirements-docs.txt diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..c0351c3 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,78 @@ +name: Docs + +# Build the MkDocs Material site and deploy it to GitHub Pages. +# +# One-time setup required: in the repo, go to Settings → Pages and set +# "Source" to "GitHub Actions". After that, every push to main that touches the +# docs builds and publishes automatically. + +on: + push: + branches: [main] + paths: + - docs/** + - mkdocs.yml + - requirements-docs.txt + - .github/workflows/docs.yml + pull_request: + branches: [main] + paths: + - docs/** + - mkdocs.yml + - requirements-docs.txt + - .github/workflows/docs.yml + # Allow manual runs from the Actions tab. + workflow_dispatch: + +# Cancel superseded runs on the same PR/branch to save runner minutes. +concurrency: + group: docs-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build site + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + cache: pip + cache-dependency-path: requirements-docs.txt + + - name: Install dependencies + run: pip install -r requirements-docs.txt + + # --strict turns warnings (broken nav links, missing images/refs) into + # errors, so a bad doc fails the build instead of shipping silently. + - name: Build site + run: mkdocs build --strict + + - name: Upload Pages artifact + # Only publish from main; PRs build-check only (see deploy job's `if`). + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + name: Deploy to GitHub Pages + # Only deploy on pushes to main, never on PRs. + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 743bca4..882492a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,10 @@ fastlane/test_output # Local scratch / planning notes tasks/ +# Docs site (MkDocs Material) — local build output + virtualenv +site/ +.venv-docs/ + # Misc *.log *~ diff --git a/README.md b/README.md index 149de1e..5809845 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@

- - PulseLoop + + PulseLoop

@@ -203,15 +203,15 @@ raw value; steps and distance are shown. **System architecture:** four layers on the phone. Data flows up from the ring into local storage; the coach reads sideways through tools, and the only thing that leaves the device is a coach question you choose to ask. -[![System architecture](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/system-architecture.png)](/docs/system-architecture.png) +[![System architecture](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/system-architecture.png)](/docs/images/system-architecture.png) **The ring link:** one custom BLE service, fixed 20-byte cleartext packets, commands out and notifications back. -[![Ring interaction](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/ble-interaction.png)](/docs/ble-interaction.png) +[![Ring interaction](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/ble-interaction.png)](/docs/images/ble-interaction.png) **The AI coach:** an agentic loop that calls tools to read your local data, then answers in a structured format. -[![AI coach](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/AI-coach-design.png)](/docs/AI-coach-design.png) +[![AI coach](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/AI-coach-design.png)](/docs/images/AI-coach-design.png) --- diff --git a/docs/assets/logo.svg b/docs/assets/logo.svg new file mode 100644 index 0000000..4c59d0f --- /dev/null +++ b/docs/assets/logo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/docs/getting-started/android.md b/docs/getting-started/android.md new file mode 100644 index 0000000..60cc1da --- /dev/null +++ b/docs/getting-started/android.md @@ -0,0 +1,95 @@ +--- +title: Getting Started — Android +description: Install and build PulseLoop for Android, and what the Android port adds. +--- + +# Getting Started on Android + +PulseLoop has a sister project for Android: +**[foureight84/PulseLoopAndroid](https://github.com/foureight84/PulseLoopAndroid)**. + +The two ports are developed hand in hand and share the same BLE protocol work, so +a fix or a newly decoded sensor on one platform usually lands on the other. The +Android build is written in **Jetpack Compose + Material 3** with **Room** for +persistence, and adds several platform-specific niceties on top of the shared +feature set. + +!!! info "Pick a ring first" + PulseLoop talks to a real Bluetooth ring. Check the + [supported hardware](../hardware/index.md) before you start — both + ports connect to the same rings. + +## :material-android: Install + +The Android app is distributed from the +[PulseLoopAndroid repository](https://github.com/foureight84/PulseLoopAndroid). +Check that repo's releases and README for the latest APK and install +instructions. + +## :material-hammer-wrench: Build from source + +!!! note "Build steps live in the Android repo" + Android build instructions are maintained in the + [PulseLoopAndroid README](https://github.com/foureight84/PulseLoopAndroid). + The outline below is the typical Android Studio flow; **follow the Android + repo's README for the authoritative, up-to-date steps.** + + + +1. Clone [foureight84/PulseLoopAndroid](https://github.com/foureight84/PulseLoopAndroid). +2. Open the project in **Android Studio**. +3. Let Gradle sync, then connect a physical Android device — Bluetooth LE needs + real hardware. +4. Build & run the app module to your device. +5. On first launch, grant Bluetooth/Location permissions and keep the ring nearby. +6. To enable the Coach, open **Settings** and add your OpenAI or Gemini API key. + It's stored in `EncryptedSharedPreferences` and only used to call the model + you choose. + +## What the Android port adds + +Beyond the shared dashboards and AI Coach, the Android build includes extra +features that aren't (yet) in the iOS app: + +- **Full `0x24` sensor decoding** — fatigue, stress, blood sugar, and HRV from + the combined-measurement packet. +- **Ring configuration & calibration** — user profile (age/sex/height/weight), + BP cuff-reference calibration, and a blood-sugar lab offset, all in Settings. +- **Bind/unbind protocol** — proper ring claiming on connect and release on + forget, so the ring re-advertises for other apps. +- **Connection reliability** — keepalive pings, a write-ACK timeout, and a + connection watchdog that prevents silent disconnects. +- **Vitals detail screens** — tap any metric for a trend chart, period selector, + stat tiles, and a color-coded threshold bar. +- **Threshold bars everywhere** — color-coded reference ranges (Good → Normal → + Borderline → High) on every vitals panel. +- **Combined measurement button** — one tap for BP + SpO₂ + stress + fatigue + + blood sugar with a countdown. +- **Pull-to-refresh** — triggers an immediate ring sync from the Today dashboard. + +For the complete, current breakdown, see the +[iOS vs Android comparison](../platforms/ios-vs-android.md). + +## Architecture at a glance + +| Aspect | Android | +| --- | --- | +| UI | Jetpack Compose + Material 3 | +| Persistence | Room (SQLite) | +| BLE | `android.bluetooth.le` | +| HTTP | OkHttp | +| Key storage | `EncryptedSharedPreferences` | +| Background work | WorkManager | +| Charts | Custom Compose Canvas | + +See the [Architecture](../project/architecture.md) page for how both ports map +onto the same data flow. + +## Next steps + +- [Supported hardware](../hardware/index.md) — what each ring can do. +- [iOS vs Android](../platforms/ios-vs-android.md) — where the ports differ today. +- [Contributing](../project/contributing.md) — coordinate cross-platform work in + the [Discord](https://discord.gg/t9y85ebaKD). +- Looking for iOS? See [Getting Started on iOS](ios.md). diff --git a/docs/getting-started/ios.md b/docs/getting-started/ios.md new file mode 100644 index 0000000..31cf67e --- /dev/null +++ b/docs/getting-started/ios.md @@ -0,0 +1,83 @@ +--- +title: Getting Started — iOS +description: Install PulseLoop on iOS via TestFlight or build it from source in Xcode. +--- + +# Getting Started on iOS + +PulseLoop for iOS is a native SwiftUI app with SwiftData persistence, Live +Activities, and a Dynamic Island widget. There are two ways to run it: the +upcoming public TestFlight beta, or building from source in Xcode. + +!!! info "Pick a ring first" + PulseLoop talks to a real Bluetooth ring. Before you start, check the + [supported hardware](../hardware/index.md) to make sure your ring + is one PulseLoop can drive. No ring yet? You can still explore the whole app + with [demo data](#demo-data-no-ring-required). + +## :material-apple: TestFlight beta + +A public TestFlight beta is coming soon. Sign up on the +[Discord](https://discord.gg/t9y85ebaKD) to get the invite link. An IPA release +is also planned. + +## :material-hammer-wrench: Build from source (Xcode) + +### Requirements + +- **Xcode 16+** on macOS. +- An **iOS 18+ physical device** — Bluetooth and Live Activities need real + hardware, so the simulator can't reach the ring. +- A compatible `56ff` or Colmi/Yawell BLE ring (see + [supported rings](../hardware/index.md)). +- An **OpenAI or Gemini API key** — only needed for the AI Coach features. + +### Run it + +1. Open `PulseLoop.xcodeproj` in Xcode. +2. Select the **`PulseLoop`** scheme and your physical device as the run target. +3. Under **Signing & Capabilities**, set your own **Team** and a unique **Bundle + Identifier**. + + !!! warning "The Live Activity extension needs this too" + The `PulseLoopLiveActivity` extension target is a *separate* target — + give it your team and a unique bundle ID as well, or the build will fail + to sign. + +4. Build & run (`⌘R`). +5. On first launch, complete onboarding, then keep the ring nearby — the app + auto-scans and connects when Bluetooth powers on. +6. To enable the Coach, open **Settings → Coach** and paste your API key, then + pick a provider and model. The key is stored in the iOS Keychain and never + leaves the device except to call the model you chose. + +### Demo data (no ring required) + +You can explore the whole UI and coach without any hardware: + +- **Settings → "Reseed demo data"**, or +- Launch with the `-seedDemo YES` argument. + +## Running the tests + +The unit tests in `PulseLoopTests/` are hermetic — in-memory SwiftData and a +mocked client, so they need no network and no secrets. + +- In Xcode: `⌘U`. +- From the CLI: + + ```sh + xcodebuild test \ + -project PulseLoop.xcodeproj \ + -scheme PulseLoop \ + -destination 'platform=iOS Simulator,name=iPhone 16' + ``` + +CI runs this exact suite (plus SwiftLint) on every PR. + +## Next steps + +- [Supported hardware](../hardware/index.md) — what each ring can do. +- [Architecture](../project/architecture.md) — how the app is put together. +- [Contributing](../project/contributing.md) — add a ring driver or improve the coach. +- Looking for Android? See [Getting Started on Android](android.md). diff --git a/docs/hardware/colmi.md b/docs/hardware/colmi.md new file mode 100644 index 0000000..4563c60 --- /dev/null +++ b/docs/hardware/colmi.md @@ -0,0 +1,173 @@ +--- +title: Colmi / Yawell (QRing) +description: >- + The $15–30 QRing ring family (R02/R0x/R1x/H59) — Nordic-UART protocol, skin + temperature, REM sleep, and continuous background sync. +--- + +# Colmi / Yawell (QRing) + +**PulseLoop support: ✅ Supported** (R11 tested; rest implemented, needs testing 🧪) + +The QRing family — manufactured by Yawell and most commonly sold under the +**Colmi** brand. These $15–30 rings speak a Nordic-UART–based protocol and bring +sensors the cheaper [56ff / Jring](jring.md) lacks: skin temperature, REM sleep, +HRV, stress, and continuous background sync. + +## At a glance + +| | Detail | +|---|---| +| **SoC** | Realtek RTL8762 family (Realtek AB2026 on R11) | +| **Bluetooth** | BLE 5.0 | +| **PPG sensor** | Vcare VC30F (red + green dual LED) on R10/R11/R12 | +| **Accelerometer** | STK8321 / ST LIS2DOC | +| **Battery / life** | 15–18 mAh · ~4–7 days | +| **Waterproof** | IP68 / 3ATM–5ATM (varies by model) | +| **Price** | $15–30 | +| **Protocol** | Nordic-UART QRing (`6e40fff0` / `de5bf728`), 16-byte frames, cleartext | +| **App** | QRing (R11 also: Da Rings) | +| **Custom firmware** | ✅ on R02/R03 (BXMicro); ⚠️ unknown on R10/R12 | + +## Manufacturer + +- **Shenzhen Yawell Intelligent Technology Co., Ltd.** (est. 2016, Shenzhen) +- 3 factories, 16 assembly lines, 500+ workers, 100+ R&D engineers +- Largest smart ring factory in South China (5,000 m², established 2024) +- 150K+ monthly smart ring shipments +- OEM/ODM for Lenovo, Nokia, Skyworth, Noise, Titan, Fire Boltt +- First smart ring launched: 2023 +- Official app: **QRing** (by Yawell) +- **Colmi** (Shenzhen Colmi Technology Co., Ltd.) is the most popular licensed brand selling Yawell's QRing rings +- Website: [yawellfit.com](https://www.yawellfit.com/), [colmi.com](https://www.colmi.com/) + +## Protocol + +| Property | Value | +|---|---| +| **BLE family** | Nordic-UART (`6e40fff0` / `de5bf728`) | +| **App** | QRing | +| **Frame size** | 16 bytes (checksum) | +| **Encryption** | None | + +## Models — QRing platform + +| Model | CPU | Bluetooth | Battery | Waterproof | Display | Sensors | Notes | +|---|---|---|---|---|---|---|---| +| **R02** | Realtek RTL8762 | BLE 5.0 | Varies | IP68/3ATM | No | Unknown | Entry-level, "highly supported" per Gadgetbridge | +| **R03** | Realtek RTL8762 | BLE 5.0 | Varies | Unknown | No | Unknown | | +| **R06** | Realtek RTL8762 | BLE 5.0 | Varies | Unknown | No | Unknown | | +| **R07** | Realtek RTL8762 | BLE 5.0 | Varies | Unknown | No | Unknown | | +| **R09** | Realtek RTL8762 | BLE 5.0 | Varies | Unknown | No | Unknown | | +| **R10** | RTL8762 ESF | BLE 5.0 | 17 mAh | 5ATM | No | Vcare VC30F + STK8321 | Charging case: 200 mAh | +| **R12** | Realtek RTL8762 | BLE 5.0 | 15/18 mAh | IP68 + 1ATM | Yes | Vcare VC30F + ST LIS2DOC | Newest (2025), 4g weight | + +### Yawell-branded QRing models + +- R05, R10, R11, H59 — all use the same QRing protocol + +## Colmi R11 — QRing-Compatible with Fidget Shell + +The Colmi R11 uses a Realtek AB2026 SoC rather than the RTL8762 found in other QRing models, +but speaks the same Nordic-UART QRing protocol. It pairs with both the **Da Rings** app and the +**QRing** app. + +| Component | Detail | +|---|---| +| **CPU** | Realtek AB2026 | +| **Bluetooth** | BLE 5.0 | +| **PPG sensor** | Vcare VC30F (red + green dual LED) | +| **Accelerometer** | STK8321 (3-axis MEMS) | +| **Battery** | 15 mAh (sizes 8–9) / 18 mAh (sizes 10–13) | +| **Charging case** | 200 mAh | +| **Waterproof** | IP68 + 5ATM | +| **Build** | Stainless steel casing with fidget-spinner outer shell | +| **Apps** | Da Rings or QRing (Android 5.1+ / iOS 12.0+) | + +PulseLoop matches R11 rings via the `R11C?_[0-9A-F]{4}$` pattern in the Colmi QRing driver. +Capabilities should match the R10 (same VC30F + STK8321 sensor pair). + +## Sensors + +### Vcare VC30F + +The VC30F is the PPG bio-sensor used in R10, R11, and R12: + +- **Red + green LED emitters** — dual wavelength for HR and SpO₂ +- **Integrated photodiode** — detects reflected light with ambient light rejection +- **Analog front-end (AFE)** — filters and amplifies raw signal +- **Digital controller** — outputs processed pulse data +- Available on JLCPCB's parts library (traceable component) +- Real-world accuracy: within 1 BPM of medical-grade BP monitor (per R12 review) + +### ST LIS2DOC (R12) / STK8321 (R10, R11) + +3-axis MEMS accelerometer for: + +- Step counting and gesture detection +- Wear detection (wake on motion) +- Raw acceleration data for sleep and activity algorithms + +## Capabilities per model + +| Capability | R10 | R12 | R11 | Other QRing¹ | +|---|---|---|---|---| +| **Heart rate — spot** | ✅ | ✅ | ✅ | 🧪 | +| **Heart rate — history** | ✅ | ✅ | ✅ | 🧪 | +| **Heart rate — live** | ✅ | ✅ | ✅ | 🧪 | +| **SpO₂ — history** | ✅ | ✅ | ✅ | 🧪 | +| **SpO₂ — spot** | —² | —² | —² | —² | +| **Steps / distance / calories** | ✅ | ✅ | ✅ | 🧪 | +| **Sleep stages** (light/deep/awake) | ✅ | ✅ | ✅ | 🧪 | +| **REM sleep** | ✅ | ✅ | ✅ | 🧪 | +| **HRV** | ✅ | ✅ | ✅ | 🧪 | +| **Stress** | ✅ | ✅ | ✅ | 🧪 | +| **Body temperature** | ✅ | ✅ | ✅ | 🧪 | +| **Battery level** | ✅ | ✅ | ✅ | 🧪 | +| **Find device** | ✅ | ✅ | ✅ | 🧪 | +| **Blood pressure** | ❌ | ❌ | ❌ | ❌ | +| **Blood sugar** | ❌ | ❌ | ❌ | ❌ | + +¹ R02, R03, R06, R07, R09 + Yawell R05, R10, R11, H59 +² Colmi family has no on-demand SpO₂ reading; SpO₂ is all-day background only +³ Colmi has no blood pressure or blood sugar support. Its `userPreferences` (gender/age/height/weight) is for general health metric tuning only — not for BP/BS computation. + +### What the Colmi family CAN do (that 56ff cannot) + +- REM sleep detection +- Body temperature (skin temperature sensor) +- HRV +- Stress scoring +- Continuous background sync (autonomous notifications while worn) + +## Hackability + +### 🏆 Full-Stack Hackable: Colmi R02 / R03 / R06 + +Per Hackaday's deep-dive by Aaron Christophel, the Colmi R02 is the most hacker-friendly ring: + +| What | Detail | +|---|---| +| **Custom firmware** | Flashable via BLE OTA — **no signing, no encryption** | +| **Debug interface** | SWD pads accessible (scrape epoxy to expose) | +| **MCU** | BXMicro chip, 512 KB flash, 200 KB RAM | +| **SDK** | [BXMicro SDK3](https://gitee.com/BXMicro/SDK3) | +| **Reference FW** | [atc1441/ATC_RF03_Ring](https://github.com/atc1441/ATC_RF03_Ring) | +| **App protocol** | Documented in PulseLoop + Gadgetbridge | +| **Price** | $15–25 | + +The manufacturer publishes firmware update images with no authenticity checks — upload whatever you want over BLE. Combined with SWD debugging, this is the closest thing to an open-source smart ring in production. + +### 🥉 Protocol-Documented: the wider QRing family + +- ✅ BLE protocol reverse-engineered (PulseLoop + Gadgetbridge) +- ✅ Nordic-UART based, unencrypted +- ✅ Custom app possible (PulseLoop already does it) +- ⚠️ Custom firmware: confirmed possible on R02/R03 (BXMicro); unknown for R10/R12 (Realtek RTL8762) +- **Price:** $15–30 + +--- + +See the [hardware overview](index.md) for the full cross-manufacturer comparison +tables, or the [Jring / 56ff](jring.md) page for the cheaper option (the only one +with BP/blood sugar). diff --git a/docs/hardware/index.md b/docs/hardware/index.md new file mode 100644 index 0000000..da8c07f --- /dev/null +++ b/docs/hardware/index.md @@ -0,0 +1,246 @@ +--- +title: Supported Hardware +description: >- + Hardware specs, capabilities, and hackability for every smart ring PulseLoop + supports — shared across the iOS and Android ports. +--- + +# Supported Hardware + +PulseLoop is built around a **device-agnostic driver layer**, so each supported +ring declares exactly what it can do and the app shows only those features. This +section breaks the hardware down by manufacturer. + +!!! abstract "About these pages" + This is a cross-platform reference shared by both the iOS and Android ports — + they drive the same rings over the same reverse-engineered BLE protocols. + Compiled from project documentation, web research, product pages, and + teardowns. *Last updated: 2026-06-25.* + +!!! warning "No affiliation" + PulseLoop has no affiliation with the sellers or manufacturers of any ring + listed here. Listings are for convenience only — links may break, sellers may + swap hardware under the same name, and your unit may behave differently. Buy + at your own risk and treat any data the ring produces as approximate. + +## Browse by manufacturer + +
+ +- :material-ring: __Jring / 56ff__ + + --- + + The $7–12 commodity ring (keeprapid OEM). Custom `56ff` protocol. The only + PulseLoop-supported ring with blood pressure and blood sugar. + + [:octicons-arrow-right-24: Jring / 56ff](jring.md) + +- :material-ring: __Colmi / Yawell (QRing)__ + + --- + + The $15–30 QRing family — R02/R0x/R1x/H59. Nordic-UART protocol, skin + temperature, REM sleep, and continuous background sync. + + [:octicons-arrow-right-24: Colmi / Yawell](colmi.md) + +- :material-help-circle-outline: __SIMSONLAB__ + + --- + + Not supported — unknown protocol on a Phyplus PHY6222 SoC, with no public + reverse engineering. Documented here for reference. + + [:octicons-arrow-right-24: SIMSONLAB](simsonlab.md) + +- :material-crown-outline: __Premium rings__ + + --- + + Oura, Ultrahuman, and RingConn. Not currently supported (Ultrahuman's + protocol is documented and on the roadmap). Documented for reference. + + [:octicons-arrow-right-24: Premium rings](premium.md) + +
+ +## Supported Rings — Hardware Specs + +!!! info "Legend" + - ✅ — yes / supported + - ❌ — no / not supported + - ❓ — unknown + +| | 56ff / Jring | Colmi R02/R03/etc | Colmi R10 | Colmi R12 | Colmi R11 | +|---|---:|---:|---:|---:|---:| +| **SoC** | Renesas DA14531 | Realtek RTL8762 | RTL8762 ESF | Realtek RTL8762 | Realtek AB2026 | +| **Architecture** | ARM Cortex-M0 | ARM | ARM | ARM | ARM | +| **Bluetooth** | BLE 5.x | BLE 5.0 | BLE 5.0 | BLE 5.0 | BLE 5.0 | +| **PPG sensor** | Unknown (HR/SpO₂) | Unknown | Vcare VC30F | Vcare VC30F | Vcare VC30F | +| **PPG LEDs** | Unknown | Unknown | Red + green (dual) | Red + green (dual) | Red + green (dual) | +| **Accelerometer** | Yes | Unknown | STK8321 | ST LIS2DOC | STK8321 | +| **Skin temperature** | ❌ | ❓ | ✅ | ✅ | ✅ | +| **Battery** | Unknown | Varies | 17 mAh | 15–18 mAh | 15–18 mAh¹ | +| **Battery life** | Unknown | Varies | ~4–7 days | ~4–7 days | ~4–7 days | +| **Charging case** | ❌ | ❌ | ✅ (200 mAh) | ❌ | ✅ (200 mAh) | +| **Display** | ❌ | ❌ | ❌ | ✅ | ❌ | +| **Waterproof** | Varies by seller | IP68 / 3ATM | 5ATM | IP68 + 1ATM | IP68 + 5ATM | +| **Weight** | Unknown | Unknown | Unknown | ~4 g | Unknown | +| **Price** | $7–12 | $15–25 | $15–25 | ~$30 | ~$15–25 | +| **Protocol** | Custom 56ff | Nordic-UART QRing | Nordic-UART QRing | Nordic-UART QRing | Nordic-UART QRing² | +| **Frame size** | Fixed 20 bytes | 16 bytes (checksum) | 16 bytes (checksum) | 16 bytes (checksum) | 16 bytes (checksum) | +| **Encryption** | None | None | None | None | None | +| **FW OTA** | ✅ Renesas SUOTA | ✅ BLE OTA (no sign) | ❓ | ❓ | ❓ | +| **Custom firmware** | ✅ (SR08 ref) | ✅ (RF03 ref) | ❓ | ❓ | ❓ | +| **PulseLoop support** | ✅ | ✅ | ✅ | ✅ | ✅ | + +¹ 15 mAh for sizes 8–9, 18 mAh for sizes 10–13. +² Works with the QRing app; also has a companion "Da Rings" app. Matched by Colmi driver. + +## Supported Rings — Capabilities + +| Capability | 56ff / Jring | Colmi R02/etc | Colmi R10 | Colmi R12 | Colmi R11 | +|---|---:|---:|---:|---:|---:| +| Heart rate — spot | ✅ | ✅ | ✅ | ✅ | ✅ | +| Heart rate — history | ✅ | ✅ | ✅ | ✅ | ✅ | +| Heart rate — live | ✅ | ✅ | ✅ | ✅ | ✅ | +| SpO₂ — history | ✅ | ✅ | ✅ | ✅ | ✅ | +| SpO₂ — spot | ✅ | ❌¹ | ❌¹ | ❌¹ | ❌¹ | +| Steps / distance / calories | ✅ | ✅ | ✅ | ✅ | ✅ | +| Sleep (light/deep/awake) | ✅ | ✅ | ✅ | ✅ | ✅ | +| REM sleep | ❌ | ✅ | ✅ | ✅ | ✅ | +| Blood pressure | ✅² | ❌ | ❌ | ❌ | ❌ | +| Blood sugar | ✅³ | ❌ | ❌ | ❌ | ❌ | +| HRV | ✅ | ✅ | ✅ | ✅ | ✅ | +| Stress | ✅ | ✅ | ✅ | ✅ | ✅ | +| Fatigue | ✅ | ✅ | ✅ | ✅ | ✅ | +| Skin temperature | ❌ | ✅ | ✅ | ✅ | ✅ | +| Battery level | ✅ | ✅ | ✅ | ✅ | ✅ | +| Find device | ✅ | ✅ | ✅ | ✅ | ✅ | +| Continuous background sync | ❌ | ✅ | ✅ | ✅ | ✅ | +| FW update via app | ✅ | ✅ | ❓ | ❓ | ❓ | + +¹ Colmi family has no on-demand SpO₂ reading; SpO₂ is all-day background only. +² Direct PPG sensor reading, no user profile required. +³ Profile-derived estimate from sex/age/height/weight, not a real glucometer reading. + +## Not Supported by PulseLoop + +| Ring | Reason | +|---|---| +| **SIMSONLAB LA380-YJ** | Unknown protocol (PHY6222 SoC), no reverse engineering — see [SIMSONLAB](simsonlab.md) | +| **Oura Gen 3/4** | Encrypted BLE, proprietary protocol, subscription required — see [Premium rings](premium.md) | +| **Ultrahuman Ring Air** | Not yet implemented (protocol is documented) — see [Premium rings](premium.md) | +| **RingConn Gen 2** | No public protocol, no reverse engineering — see [Premium rings](premium.md) | + +--- + +## Platform Overview + +Multiple hardware platforms span from $7 commodity rings to $350 premium devices: + +### Budget / Commodity Rings + +| Platform | SoC | Protocol | App | Price | Hackable | +|---|---|---|---|---|---| +| **[56ff / Jring](jring.md)** | Renesas DA14531 | Custom 56ff (SXR KeepFit SDK) | Jring / KeepFit | $7–12 | ✅ App + FW | +| **[Colmi / Yawell (QRing)](colmi.md)** | Realtek RTL8762 family | Nordic-UART (QRing) | QRing | $15–30 | ✅ App (R02 FW too) | +| **[Colmi R11](colmi.md#colmi-r11-qring-compatible-with-fidget-shell)** | Realtek AB2026 | Nordic-UART QRing | QRing / Da Rings | ~$15–25 | ✅ App (untested) | +| **[SIMSONLAB](simsonlab.md)** | Phyplus PHY6222 | Unknown | SIMSONLAB app | ~$10–20 | ❌ | + +### Premium Rings + +| Platform | SoC | Protocol | App | Price | Subscription | Hackable | +|---|---|---|---|---|---|---| +| **[Oura Gen 4](premium.md#oura-ring-gen-3-gen-4)** | Nordic nRF52840 | Encrypted proprietary | Oura app | $349 | **$5.99/mo required** | ❌ | +| **[Ultrahuman Ring Air](premium.md#ultrahuman-ring-air)** | nRF52840 + STM32G0 | Documented (Gadgetbridge) | Ultrahuman | $349 | ❌ None | ✅ App protocol | +| **[RingConn Gen 2 Air](premium.md#ringconn-gen-2-gen-2-air)** | Unknown (Nordic likely) | Proprietary | RingConn | $199 | ❌ None | ❌ | + +--- + +## Hackability Summary + +A breakdown of which rings can be used with custom software or firmware. For the +full detail, see each manufacturer's page. + +| Ring | Custom App | Custom Firmware | Price | +|---|---|---|---| +| **[Colmi R02/R03](colmi.md)** | ✅ PulseLoop, Gadgetbridge | ✅ OTA, SWD, SDK | $15–25 | +| **[56ff / Jring](jring.md)** | ✅ PulseLoop, Gadgetbridge | ✅ SUOTA, open-source FW | $7–12 | +| **[Colmi R10/R12](colmi.md)** | ✅ PulseLoop, Gadgetbridge | ❓ Unknown (Realtek locked?) | $15–30 | +| **[Ultrahuman Ring Air](premium.md#ultrahuman-ring-air)** | ✅ Gadgetbridge protocol | ❌ nRF locked | $349 | +| **[RingConn Gen 2](premium.md#ringconn-gen-2-gen-2-air)** | ❌ No public protocol | ❌ | $199–299 | +| **[Oura Ring](premium.md#oura-ring-gen-3-gen-4)** | ❌ Encrypted BLE | ❌ | $349 + sub | +| **[SIMSONLAB](simsonlab.md)** | ❌ Unknown protocol | ❌ | $10–20 | + +### Open-Source DIY Platforms + +| Project | Detail | +|---|---| +| **[Open Ring](https://github.com/stawiski/open-ring)** | Open-source hardware + firmware reference design | +| **KuoQuo's smart ring dev board** | nRF-based I2C sensor platform, designed for firmware hacking | +| **[ATC_SR08_Ring](https://github.com/atc1441/ATC_SR08_Ring)** | Open-source firmware for 56ff/Jring hardware | +| **[ATC_RF03_Ring](https://github.com/atc1441/ATC_RF03_Ring)** | Open-source firmware for Colmi R02/R03 hardware | +| **[ringverse/protocol](https://github.com/ringverse/protocol)** | Community reverse engineering of smart ring protocols | + +--- + +## Quick Comparison + +### Sensor quality + +| | VC30F (Colmi R10/R12) | HX3602 (SIMSONLAB) | Unknown PPG (56ff) | +|---|---|---|---| +| **LEDs** | Red + green (dual) | Unknown | Unknown | +| **SpO₂ capable** | ✅ (red LED) | ❓ | ✅ | +| **Datasheet** | Public (JLCPCB) | None found | None found | +| **Verified accuracy** | ±1 BPM vs medical device | No testing found | No testing found | + +### Chipset comparison + +| | DA14531 (56ff) | RTL8762 (Colmi QRing) | AB2026 (Colmi R11) | PHY6222 (SIMSONLAB) | +|---|---|---|---|---| +| **Vendor** | Renesas | Realtek | Realtek | Phyplus | +| **Architecture** | ARM Cortex-M0 | ARM | ARM | ARM Cortex-M0 | +| **Bluetooth** | BLE 5.x | BLE 5.0 | BLE 5.2 | BLE 5.1 | +| **Memory** | Unknown | Unknown | Unknown | 512 KB built-in | +| **Known from** | Jring, KeepFit, RWfit, Tag | Colmi R02–R10, R12, Yawell | Colmi R11 | SIMSONLAB LA380-YJ, various watches | + +### Which to choose? + +| If you want... | Pick | +|---|---| +| **Cheapest possible** ($7–12) | [56ff / Jring](jring.md) | +| **Most sensors** (temp, HRV, REM, stress) | [Colmi R10 or R12](colmi.md) ($15–30) | +| **Best battery** | [Colmi R10](colmi.md) (17 mAh + 200 mAh case, no display) | +| **On-ring display** | [Colmi R12](colmi.md) | +| **Best waterproofing** | [Colmi R10 or R11](colmi.md) (5ATM) | +| **Best HR accuracy** | [Colmi R10/R12](colmi.md) (VC30F sensor, verified accuracy) | +| **Works with PulseLoop today** | [56ff Jring](jring.md) or [Colmi QRing family](colmi.md) | + +--- + +## References + +- **56ff protocol reverse-engineering writeup**: [sakshambhutani.xyz/hacking/2_hacking/](https://sakshambhutani.xyz/hacking/2_hacking/) +- **PulseLoop protocol docs** (in the iOS repo): `docs/ring-protocol.md`, `docs/protocol-discoveries.md`, `docs/keepfit-protocol-complete.md` +- **Gadgetbridge Yawell/Colmi page**: [gadgetbridge.org/gadgets/wearables/yawell/](https://gadgetbridge.org/gadgets/wearables/yawell/) +- **Gadgetbridge KeepFit PR**: [#5326](https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5326) +- **Open-source ring firmware**: [atc1441/ATC_SR08_Ring](https://github.com/atc1441/ATC_SR08_Ring) +- **Official KeepFit SDK/protocol**: [keeprapid/krwatch](https://github.com/keeprapid/krwatch) +- **Ring reverse engineering**: [ringverse/protocol](https://github.com/ringverse/protocol) +- **Colmi R12 review** (Walter Shillington, Medium, 2026-03-05) +- **Colmi R10 review** (ShaunChng.com) +- **SIMSONLAB LA380-YJ user manual** (device.report) +- **PHY6222 datasheet** (Phyplus Technologies) +- **Yawell company profile**: [yawellfit.com](https://www.yawellfit.com/p/about.html) +- **Colmi official**: [colmi.com](https://www.colmi.com/), [colmi.info](https://www.colmi.info/) +- **Ultrahuman Protocol (Gadgetbridge)**: [gadgetbridge.org/internals/specifics/ultrahuman-protocol/](https://gadgetbridge.org/internals/specifics/ultrahuman-protocol/) +- **Hackaday — Hackable Smart Ring**: [New Part Day: A Hackable Smart Ring](https://hackaday.com/2024/06/16/new-part-day-a-hackable-smart-ring/) +- **ATC_RF03_Ring (custom FW for Colmi R02)**: [github.com/atc1441/ATC_RF03_Ring](https://github.com/atc1441/ATC_RF03_Ring) +- **Open Ring (open-source HW/FW)**: [github.com/stawiski/open-ring](https://github.com/stawiski/open-ring) +- **Ultrahuman Ring Air teardown**: [makingstudio.blog](https://makingstudio.blog/2024/09/10/ultrahuman-ring-air-teardown/) +- **Oura Ring teardown (Becky Stern)**: [beckystern.com](https://beckystern.com/2022/04/17/oura-ring-teardown-gen-3-and-gen-2/) +- **Oura Ring 4 deep-dive (EDN)**: [edn.com](https://www.edn.com/the-oura-ring-4-does-one-more-deliver-much-if-any-more/) +- **Wareable best smart rings 2026**: [wareable.com](https://www.wareable.com/fashion/best-smart-rings-1340) diff --git a/docs/hardware/jring.md b/docs/hardware/jring.md new file mode 100644 index 0000000..ddbf8a5 --- /dev/null +++ b/docs/hardware/jring.md @@ -0,0 +1,132 @@ +--- +title: Jring / 56ff +description: >- + The $7–12 commodity smart ring (keeprapid OEM) with the custom 56ff protocol — + the only PulseLoop-supported ring with blood pressure and blood sugar. +--- + +# Jring / 56ff + +**PulseLoop support: ✅ Supported & tested** + +The cheapest ring PulseLoop drives — a $7–12 commodity device built by the +keeprapid OEM and white-labeled under many brands. It speaks a custom `56ff` BLE +protocol and is the **only** PulseLoop-supported ring that reports blood pressure +and (profile-derived) blood sugar. + +## At a glance + +| | Detail | +|---|---| +| **SoC** | Renesas DA14531 (ARM Cortex-M0) | +| **Bluetooth** | BLE 5.x | +| **PPG sensor** | Unknown (HR/SpO₂, no skin temperature) | +| **Accelerometer** | Yes | +| **Battery / life** | Unknown | +| **Waterproof** | Varies by seller | +| **Price** | $7–12 | +| **Protocol** | Custom 56ff (SXR KeepFit SDK), fixed 20-byte frames, cleartext | +| **App** | Jring / KeepFit | +| **Custom firmware** | ✅ Renesas SUOTA (SR08 reference) | + +## Manufacturer + +- **keeprapid.com** (ShenXinRui / 深新锐) — Chinese OEM +- White-labels under brands: **Jring, KeepFit, JYouPro, RWfit, Tag** +- SDK: SXR KeepFit SDK (`com.sxr.sdk.ble.keepfit`) + +## Hardware + +| Component | Detail | +|---|---| +| **SoC** | Renesas DA14531 (Dialog DA145XX family) | +| **SoC architecture** | ARM Cortex-M0 | +| **PPG sensor** | Unknown (PPG HR/SpO₂, no skin temperature) | +| **Accelerometer** | Yes (steps, sleep stages, activity) | +| **Memory** | Unknown | +| **Weight** | Unknown | +| **Waterproof** | Unknown (varies by seller) | + +## Protocol + +The `56ff` protocol was reverse-engineered from scratch — see the +[full writeup](https://sakshambhutani.xyz/hacking/2_hacking/) for the BLE +teardown and how the packet formats were decoded. + +| Property | Value | +|---|---| +| **Service UUID** | `000056ff-0000-1000-8000-00805f9b34fb` | +| **Write characteristic** | `000033f3-...` | +| **Notify characteristic** | `000033f4-...` | +| **Additional chars** | `0x33F5`, `0x33F6` (purpose unknown) | +| **Secondary service** | `0x57FF` | +| **SUOTA service** | `0000fef5-...` (firmware OTA) | +| **Frame size** | Fixed 20 bytes | +| **Encryption** | None (cleartext) | +| **Standard BLE services** | DIS (`0x180A`), Heart Rate Service (`0x180D`) | + +## Capabilities + +| Capability | Status | Notes | +|---|:---:|---| +| Heart rate — spot / live / history | ✅ | BPM | +| SpO₂ — spot / history | ✅ | | +| Steps / distance / calories | ✅ | | +| Sleep (light / deep / awake) | ✅ | No REM | +| Blood pressure | ✅ | Direct sensor reading via `0x23`/`0x24`, no user profile required | +| Blood sugar | ✅ | Profile-derived estimate (not a real glucometer) — requires user profile | +| Stress | ✅ | 0–100 | +| Fatigue | ✅ | 0–100 | +| HRV | ✅ | ms | +| Battery level | ✅ | | +| Find device | ✅ | | +| REM sleep | ❌ | | +| Skin temperature | ❌ | No sensor — official app shows 0°C/32°F placeholder | +| Continuous background sync | ❌ | Command-response only, ~20s idle timeout | + +!!! info "Blood sugar requires a user profile" + Blood sugar is a profile-derived *estimate* from sex/age/height/weight (sent + via `0x02` `CMD_SET_USER_INFO`), not a real glucometer reading — changing the + profile changes the value. + +### What the 56ff ring CANNOT do + +- REM sleep detection +- Body temperature (no skin temperature sensor) +- Continuous streaming (command-response only, ~20s idle timeout) + +## Known models + +- **SR08** — open-source reference hardware ([atc1441/ATC_SR08_Ring](https://github.com/atc1441/ATC_SR08_Ring)) +- Generic "SMART_RING" — sold on AliExpress for $7–12 + +## Firmware + +- Firmware check: `http://download.keeprapid.com/apps/smartband/jring/autoupdater/{device_id}/update.json` +- Binary download: `http://download.keeprapid.com:8181/docs/jring/an_{p1}_{p2}1` +- Flashing: Renesas SUOTA (`0xFEF5` service) to DA14531 +- Version format: `"003A002AV138"` (status hex + V + version number) +- **All API traffic is HTTP (not HTTPS) — unencrypted** + +## Background behavior + +- Idle timeout: ~20 seconds of inactivity +- Keepalive: `0x3A` ping/pong +- Binding: `0x4B` custom protocol (NOT OS `createBond()`) +- Official app runs periodic background sync + +## Hackability + +**🥈 Protocol-Documented** + +- ✅ Protocol fully reverse-engineered ([writeup](https://sakshambhutani.xyz/hacking/2_hacking/); also the iOS repo's `docs/ring-protocol.md`) +- ✅ Open-source firmware skeleton: [atc1441/ATC_SR08_Ring](https://github.com/atc1441/ATC_SR08_Ring) +- ✅ Official SDK protocol doc: `深新锐蓝牙协议v3.0.docx` (keeprapid/krwatch) +- ✅ Cleartext BLE, no encryption +- ✅ Renesas SUOTA for firmware OTA +- **Price:** $7–12 + +--- + +See the [hardware overview](index.md) for the full cross-manufacturer comparison +tables, or the [Colmi / Yawell](colmi.md) family for the more sensor-rich option. diff --git a/docs/hardware/premium.md b/docs/hardware/premium.md new file mode 100644 index 0000000..78445b9 --- /dev/null +++ b/docs/hardware/premium.md @@ -0,0 +1,102 @@ +--- +title: Premium Rings +description: >- + Oura, Ultrahuman, and RingConn — premium rings not currently supported by + PulseLoop. Ultrahuman's protocol is documented and on the roadmap. +--- + +# Premium Rings + +**PulseLoop support: ❌ Not currently supported** + +These rings compete with Oura on hardware quality but mostly without the +subscription lock-in. None are supported by PulseLoop today, though the +[Ultrahuman Ring Air](#ultrahuman-ring-air) is the most promising candidate — its +protocol is fully documented and it's on the [roadmap](../project/roadmap.md). + +| Ring | Why it isn't supported (yet) | +|---|---| +| **Oura Gen 3/4** | Encrypted BLE, proprietary protocol, subscription required | +| **Ultrahuman Ring Air** | Not yet implemented — but the protocol *is* documented | +| **RingConn Gen 2 / Air** | No public protocol, no reverse engineering | + +## Oura Ring (Gen 3 / Gen 4) + +| Component | Gen 3 (2021) | Gen 4 (2024) | +|---|---|---| +| **SoC** | Nordic nRF52840 (Cortex-M4F, 64 MHz, 1 MB flash, 256 KB RAM) | Nordic nRF52840 | +| **PPG** | 2× green LED + red/IR multi-chip LED + 2× photodiodes | 2 clusters × green/red/IR LEDs + 3× photodiodes, 18-path multi-wavelength | +| **Temperature** | NTC thermistor (indirect) | NTC thermistor (indirect) | +| **Accelerometer** | 3-axis | 3-axis | +| **Battery** | 16 mAh (Grepow YE160723G) | 26 mAh | +| **Battery life** | 4–7 days | Up to 8 days | +| **Battery management** | TI BQ25120A | Unknown | +| **Charging** | Wireless inductive | Wireless inductive | +| **Price** | $299+ (discontinued) | $349 + **$5.99/mo subscription required** | +| **BLE** | Encrypted, proprietary | Encrypted, proprietary | +| **Open docs** | ❌ Completely closed | ❌ Completely closed | + +**Hackability:** ❌ Fully locked down — encrypted BLE, proprietary protocol, no +public docs, subscription-gated features. + +## Ultrahuman Ring Air + +| Component | Detail | +|---|---| +| **BLE SoC** | Nordic nRF52840 (Cortex-M4F, 64 MHz, 1 MB flash, 256 KB RAM, BLE 5.0) | +| **Coprocessor** | STM32G0 (STMicro) — dedicated sensor DSP | +| **Sensors** | PPG (HR, HRV, SpO₂), skin temperature, 3-axis accelerometer | +| **Battery** | ~4–6 days | +| **Price** | $349, **no subscription** | +| **Open docs** | ✅ BLE protocol fully documented by Gadgetbridge | + +**Dual-MCU architecture:** The nRF52840 handles BLE + main processing, while the STM32G0 coprocessor runs sensor data processing and power management — arguably more capable than Oura's single-MCU design. + +**BLE Protocol (Gadgetbridge):** + +- Device name: `UH_XXXXXXXXXXXXXXXX` +- Device State service: `86f61000-f706-58a0-95b2-1fb9261e4dc7` — battery level, charging state, temperature +- Command service: `86f65000-f706-58a0-95b2-1fb9261e4dc7` — opcodes for set time, get recordings, airplane mode, reset, power saving +- All opcodes and payload formats documented + +**Hackability:** 🥈 Protocol-documented. + +- ✅ Full BLE protocol documented on [Gadgetbridge](https://gadgetbridge.org/internals/specifics/ultrahuman-protocol/) +- ✅ Every service UUID, opcode, and payload layout is public +- ✅ You can write a custom app that talks directly to the ring — no vendor app needed +- ❌ Custom firmware unlikely — nRF52840 typically has readback protection enabled + +!!! tip "On the roadmap" + Because the Ultrahuman protocol is fully public, it's the most realistic + premium ring for PulseLoop to add next. See the + [roadmap](../project/roadmap.md). + +## RingConn Gen 2 / Gen 2 Air + +| Component | Detail | +|---|---| +| **Sensors** | PPG (HR, HRV, SpO₂), skin temperature, 3-axis accelerometer | +| **Battery** | 10+ days (class-leading) | +| **Price** | Gen 2: $299 / Gen 2 Air: **$199**, **no subscription** | +| **Open docs** | ❌ No known reverse engineering or public protocol docs | + +**Hackability:** ❌ Fully locked down — no known reverse engineering, no public +protocol docs. + +## Premium Ring Comparison + +| | Oura Gen 4 | Ultrahuman Air | RingConn G2 Air | +|---|---|---|---| +| **SoC** | nRF52840 | nRF52840 + STM32G0 | Unknown (likely Nordic) | +| **Architecture** | Cortex-M4F | Cortex-M4F + Cortex-M0 | Unknown | +| **PPG** | Custom 18-path | Multi-LED | Multi-LED | +| **Temperature** | NTC thermistor | ✅ Skin temp | ✅ Skin temp | +| **Battery** | 8 days | 4–6 days | 10+ days | +| **Subscription** | **$5.99/mo required** | ❌ None | ❌ None | +| **Price** | $349 + sub | $349 | $199 | +| **Protocol open** | ❌ | ✅ (Gadgetbridge) | ❌ | +| **Custom firmware** | ❌ | ❌ (nRF locked) | ❌ | + +--- + +See the [hardware overview](index.md) for the rings PulseLoop currently supports. diff --git a/docs/hardware/simsonlab.md b/docs/hardware/simsonlab.md new file mode 100644 index 0000000..7c19ae6 --- /dev/null +++ b/docs/hardware/simsonlab.md @@ -0,0 +1,59 @@ +--- +title: SIMSONLAB +description: >- + The SIMSONLAB LA380-YJ — not supported by PulseLoop. Unknown protocol on a + Phyplus PHY6222 SoC with no public reverse engineering. +--- + +# SIMSONLAB + +**PulseLoop support: ❌ Not supported** + +The SIMSONLAB LA380-YJ uses a completely different, undocumented BLE protocol on a +Phyplus PHY6222 SoC. There's no public reverse engineering, so it isn't +compatible with any of PulseLoop's existing drivers. It's documented here for +reference and in case the protocol is ever decoded. + +!!! warning "Why it isn't supported" + Unknown, custom BLE protocol — different from both the `56ff` and QRing + families — with no public reverse engineering or datasheet to work from. + +## Manufacturer + +- **SHARE AUDIO HONG KONG LIMITED** (developer of SIMSONLAB app) +- Product appears on Shein, AliExpress, TikTok +- Model: **LA380-YJ** (2025) + +## Hardware + +| Component | Detail | +|---|---| +| **CPU** | Phyplus PHY6222 | +| **SoC architecture** | ARM Cortex-M0 32-bit | +| **Bluetooth** | BLE 5.1 | +| **Memory** | 512 KB built-in, 64 KB SRAM, 128 KB–8 MB flash | +| **HR sensor** | HX3602 | +| **Battery** | 15 mAh (magnetic charging) | +| **Standby** | 10–15 days | +| **Weight** | ~5 g | +| **Material** | Stainless steel outer, epoxy resin body | +| **Waterproof** | IP68 | +| **App** | SIMSONLAB app (iOS + Android) | + +## Protocol + +- **Unknown** — completely different from both 56ff and QRing +- Custom BLE protocol (likely) +- Not compatible with PulseLoop's existing drivers + +## HX3602 Sensor + +- Generic/low-cost heart rate sensor +- Used across many cheap Chinese wearables (SIMSONLAB rings, NKX19 watches, DaintyDelight smartwatches) +- No standalone public datasheet found +- LED configuration unknown (likely single wavelength vs VC30F's dual red+green) +- No independent accuracy testing available + +--- + +See the [hardware overview](index.md) for the rings PulseLoop *does* support. diff --git a/docs/AI-coach-design.png b/docs/images/AI-coach-design.png similarity index 100% rename from docs/AI-coach-design.png rename to docs/images/AI-coach-design.png diff --git a/docs/ble-interaction.png b/docs/images/ble-interaction.png similarity index 100% rename from docs/ble-interaction.png rename to docs/images/ble-interaction.png diff --git a/docs/system-architecture.png b/docs/images/system-architecture.png similarity index 100% rename from docs/system-architecture.png rename to docs/images/system-architecture.png diff --git a/docs/thumbnail.png b/docs/images/thumbnail.png similarity index 100% rename from docs/thumbnail.png rename to docs/images/thumbnail.png diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..d4baa39 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,131 @@ +--- +title: PulseLoop +description: >- + An LLM-native, local-first health app that turns a cheap Bluetooth smart ring + into a real, conversational health tracker — on iOS and Android. +hide: + - navigation + - toc +--- + +
+ +# PulseLoop + +

+A $20 ring + an LLM, instead of a $300 subscription wearable. +PulseLoop turns a cheap Bluetooth "smart ring" into a real, +local-first health tracker with an optional conversational AI coach — +and it runs on both iOS and Android. +

+ +
+[Get started on iOS](getting-started/ios.md){ .md-button .md-button--primary } +[Get started on Android](getting-started/android.md){ .md-button } +[Join the Discord :fontawesome-brands-discord:](https://discord.gg/t9y85ebaKD){ .md-button } +
+ +
+ +!!! tip "Why PulseLoop exists" + The goal is to prove that a **$20 ring + an LLM** can replace a **$300 + subscription wearable** — and that the "intelligence" should live on your + phone, not behind a paywall. No vendor cloud. No account. Your data stays on + your device. + +--- + +## Choose your platform + +
+ +- :material-apple: __iOS__ + + --- + + Native SwiftUI, SwiftData persistence, Live Activities, and a Dynamic Island + widget. Build from source in Xcode, or join the upcoming TestFlight beta. + + [:octicons-arrow-right-24: iOS getting started](getting-started/ios.md) + +- :material-android: __Android__ + + --- + + Jetpack Compose + Material 3, Room persistence, and extra connection-reliability + and calibration features. Developed hand-in-hand with the iOS port. + + [:octicons-arrow-right-24: Android getting started](getting-started/android.md) + +
+ +--- + +## What it does + +- **Connects to the ring over BLE** and decodes its proprietary protocol — heart + rate, SpO₂, steps, distance, calories, sleep stages, and raw packets. +- **Today / Vitals / Sleep / Activity dashboards** built natively per platform, + backed by on-device storage. +- **AI Coach** — an agentic loop (OpenAI or Google Gemini) with tools for data + retrieval, on-the-fly analysis, chart generation, long-term memory, and web + search. Every answer is grounded in *your* actual ring data. +- **Workout recording** with live heart-rate zones, GPS route maps, and a live + activity widget. +- **Daily check-in notifications** generated by the coach from your recent trends. + +--- + +## The two ports + +PulseLoop ships as two apps that are developed together and share the same +reverse-engineered BLE protocol work, so a fix or a newly decoded sensor on one +platform usually lands on the other. + +| | iOS | Android | +| --- | --- | --- | +| Repo | [saksham2001/PulseLoopiOS](https://github.com/saksham2001/PulseLoopiOS) | [foureight84/PulseLoopAndroid](https://github.com/foureight84/PulseLoopAndroid) | +| UI | SwiftUI | Jetpack Compose + Material 3 | +| Storage | SwiftData | Room (SQLite) | + +See the full [iOS vs Android comparison](platforms/ios-vs-android.md) for an +up-to-date breakdown of where the two ports differ. + +--- + +## Where to next + +
+ +- :material-ring: __Supported hardware__ + + Which rings work, what each one can do, and how hackable they are. + + [:octicons-arrow-right-24: Supported rings](hardware/index.md) + +- :material-map-marker-path: __Roadmap__ + + What's shipping next across both platforms. + + [:octicons-arrow-right-24: Roadmap](project/roadmap.md) + +- :material-sitemap: __Architecture__ + + How data flows from the ring into local storage and out to the coach. + + [:octicons-arrow-right-24: Architecture](project/architecture.md) + +- :material-shield-lock: __Privacy__ + + Local-first by design — what leaves your device and what never does. + + [:octicons-arrow-right-24: Privacy](project/privacy.md) + +
+ +--- + +!!! warning "Not a medical device" + PulseLoop is not a medical device and is not a substitute for professional + medical advice. Treat all readings as approximate, and always consult a + clinician for health concerns. diff --git a/docs/platforms/ios-vs-android.md b/docs/platforms/ios-vs-android.md new file mode 100644 index 0000000..99ae127 --- /dev/null +++ b/docs/platforms/ios-vs-android.md @@ -0,0 +1,210 @@ +--- +title: iOS vs Android +description: >- + A living comparison of where the PulseLoop iOS and Android ports differ — + protocol coverage, settings, UI, and architecture. +--- + +# iOS vs Android + +The iOS and Android ports of PulseLoop are developed hand in hand and share the +same reverse-engineered BLE protocol work. They're not identical, though — each +platform sometimes lands a feature first. This page is a **living comparison** of +where they currently differ. + +!!! note "This is a snapshot" + Things change fast. When a feature lands on both ports, it leaves this page. + *Last updated: 2026-06-25.* For the canonical state, check each repo: + [iOS](https://github.com/saksham2001/PulseLoopiOS) · + [Android](https://github.com/foureight84/PulseLoopAndroid). + +Today, the Android port is ahead in a few areas — fuller protocol decoding, ring +configuration/calibration, connection reliability, and richer vitals UI. The +sections below break that down. + +## Protocol & Ring Communication + +### Extended 0x24 Combined Sensor Decoding + +iOS only decodes bytes[1]-[4] (HR + systolic + diastolic + SpO₂) from the `0x24` combined +measurement packet. Android decodes the full 9 bytes — matching the official Jring app's +`onReceiveSensorData(i, i2, i3, i4, i5, i6, i7, i8)`: + +| Byte | Metric | iOS | Android | +|------|--------|:---:|:-------:| +| 1 | Heart Rate (BPM) | ✅ | ✅ | +| 2 | Systolic (mmHg) | ✅ | ✅ | +| 3 | Diastolic (mmHg) | ✅ | ✅ | +| 4 | SpO₂ (%) | ✅ | ✅ | +| 5 | **Fatigue** (0–100) | — | ✅ | +| 6 | **Stress** (0–100) | — | ✅ | +| 7 | **Blood Sugar** (mmol/L ×10 → mg/dL) | — | ✅ | +| 8 | **HRV** (ms) | — | ✅ | + +**iOS also mislabels the opcodes:** `spo2ResultProgress = 0x24` and `spo2Complete = 0x28`. +These are actually combined sensor data and blood data per the APK decompilation — not +SpO₂-only packets. The separate SpO₂ commands are `0x3E`/`0x3F`. + +### Ring Configuration Commands (Android-only) + +| Command | Opcode | Purpose | +|---------|--------|---------| +| **User profile** | `0x02` | Sends age/sex/height/weight to ring. Android pushes real profile from Settings on every connect; iOS sends hardcoded defaults (age 25, male, 184cm, 90kg) with no way to configure. | +| **BP calibration** | `0x33` | Sends reference systolic/diastolic to ring for on-device offset correction. iOS has no equivalent. | +| **App identity** | `0x48` | Claims the ring with a persistent app ID so it streams data to PulseLoop. Prevents mute behavior after another app claimed the ring. iOS doesn't send this. | +| **Bind/unbind** | `0x4B` | Ring-driven pairing handshake (INIT → APP_START → ACK → SUCCESS). Proper unbind (UNBOND → UNBOND_ACK) on Forget so the ring re-advertises for other apps. iOS has no bind protocol. | +| **Keepalive ping** | `0x3A` | Prevents ring's ~20s idle disconnect. Android pings every 15s. iOS has no keepalive. | + +### Connection Reliability (Android-only) + +- **Keepalive ping** — 15s interval prevents ring idle timeout +- **Write ACK timeout** — 3s timeout unblocks command queue on missed ACKs +- **Connection watchdog** — monitors GATT activity, forces reconnect after 10–20s silence +- **Foreground reconnection** — reconnects on app resume if GATT dropped during sleep +- **Stale-state guard** — resets persisted connection state on app restart +- **Force-close stale GATT** — explicitly disconnects/closes orphaned handles before new connection +- **No OS-level bonding** — avoids Bluetooth status-bar icon and OS-level pairing instability +- **High-priority connection interval** — requests priority on connect +- **Firmware discovery** — scans all BLE services for firmware characteristics, not just standard DIS + +## Settings & Calibration + +### User Profile + +| | iOS | Android | +|---|---|---| +| **Profile form** | Not configurable — hardcoded defaults always sent | Full form (age, sex, height, weight) in Settings | +| **Stored on-device** | N/A | Room database, never transmitted off-device | +| **Synced to ring** | Only hardcoded defaults at startup | Real profile pushed on connect + on save | +| **Colmi handling** | N/A | Form hidden with notice explaining Colmi doesn't need it | + +### BP Calibration + +| | iOS | Android | +|---|---|---| +| **Cuff reference entry** | Not available | Systolic/diastolic fields in Settings | +| **Sent to ring** | N/A | `0x33` command for on-device offset | +| **App-side display** | N/A | Applied in ViewModels | + +### Blood Sugar Calibration + +| | iOS | Android | +|---|---|---| +| **Lab reference entry** | Not available | mg/dL field + Calibrate button in Settings | +| **Offset method** | N/A | `glucoseOffsetMgdl = ref - latestRaw` | +| **Reset** | N/A | Reset button to clear calibration | + +## UI Differences + +### Vitals Dashboard + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Threshold bars on every metric panel | — | ✅ Color-coded (Good → Normal → Borderline → High) | +| Tap-through detail screens per metric | — | ✅ Full trend view with period selector | +| Zone-colored trend charts | — | ✅ Data points colored by threshold zone | +| Range/avg summaries on panels | — | ✅ `Range: min – max · Avg: avg` | +| Combined measurement button | — | ✅ One-tap BP+SpO₂+stress+fatigue+BS with countdown | +| Pull-to-refresh | — | ✅ Triggers immediate ring sync | + +### Vitals Detail (tap on any metric) + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Period selector (Today / Week / Month) | — | ✅ | +| Date navigator (← → arrows) | — | ✅ | +| Trend arrow + text (rising/falling/stable) | — | ✅ | +| Stat tiles (Latest · Avg · Min · Max) | — | ✅ | +| Threshold bar with zone legend | — | ✅ | +| Metric explainer text | — | ✅ | +| Medical disclaimer card | — | ✅ | + +### Colmi Ring Handling + +| Feature | iOS | Android | +|---------|:---:|:---:| +| BP/blood sugar panels hidden for Colmi | — | ✅ Capability-gated in Today and Vitals | +| Profile/calibration form hidden for Colmi | — | ✅ Notice explaining features are 56ff-only | +| Measure button hidden for Colmi | — | ✅ Gated on `supportsBP || supportsGlucose` | +| Colmi capabilities correctly declared | — | ✅ Fixed (was incorrectly including BP/BS) | + +### Ring Management + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Proper unbind on forget | — | ✅ `0x4B` UNBOND → UNBOND_ACK before teardown | +| Connection state display | — | ✅ Live status with battery % in Settings | +| Firmware version display | — | ✅ Parsed from `0x0C`/`0xF6` + standard DIS | + +### Sleep View + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Sleep stage breakdown (Deep/Light/Awake %) | — | ✅ Color-coded percentage pills | +| Sleep coach insights | — | ✅ Contextual chip-based recommendations | +| Sleep duration histogram chart | — | ✅ | +| Sleep architecture stages chart | — | ✅ | + +### Activity View + +| Feature | iOS | Android | +|---------|:---:|:---:| +| MetricThreshold reference ranges | — | ✅ Color-coded for steps/calories/distance/active minutes | +| Active minutes card with trend | — | ✅ | + +### Settings Screen + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Profile (age/sex/height/weight) | — | ✅ | +| BP calibration (systolic/diastolic) | — | ✅ | +| Blood sugar calibration (mg/dL offset) | — | ✅ | +| Unit system toggle (Metric / Imperial) | — | ✅ | +| Profile sync to ring on save | — | ✅ | +| Demo data seeder | — | ✅ | +| Ring connection management | — | ✅ Live status, firmware version, forget button | + +## Data Flow + +| Feature | iOS | Android | +|---------|:---:|:---:| +| Blood sugar (profile-derived) displayed | — | ✅ mg/dL with app-side calibration offset | +| Fatigue metric displayed | — | ✅ 0–100 scale from 0x24 byte[5] | +| Sleep REM detection (Colmi) | — | ✅ Via V2 big-data protocol | +| Skin temperature (Colmi) | — | ✅ Via V2 big-data protocol | +| Heart rate history (0x16) multi-packet | — | ✅ With sub-type routing and averaging | +| Reactive Room database with Flow | — | ✅ Live data as ring syncs | +| Local-midnight-aligned day bucketing | — | ✅ Consistent daily stats across timezones | +| Calibrated display pipeline | — | ✅ Offsets applied in ViewModels before UI | + +## Architecture + +| Aspect | iOS | Android | +|--------|-----|---------| +| Persistence | SwiftData | Room (SQLite) with 18 entities, 14 DAOs | +| BLE | CoreBluetooth | android.bluetooth.le | +| UI | SwiftUI | Jetpack Compose + Material 3 | +| HTTP | URLSession | OkHttp | +| Key storage | Keychain | EncryptedSharedPreferences | +| Background work | BGTaskScheduler | WorkManager | +| Live Activity | WidgetKit / Dynamic Island | ForegroundService + notification | +| Charts | Swift Charts | Custom Compose Canvas | +| Maps | MapKit | Canvas polyline | +| Event bus | NotificationCenter | SharedFlow | +| Notifications | UNUserNotificationCenter | NotificationManager + WorkManager | +| DI | @Environment | Manual (ViewModel factories) | + +## Summary: What Android has that iOS doesn't + +1. **Full 0x24 decoding** — fatigue, stress, blood sugar, HRV +2. **Ring configuration** — user profile (0x02), BP calibration (0x33), app ID (0x48) +3. **Bind/unbind protocol** (0x4B) — proper ring claiming and release +4. **Keepalive + connection watchdog** — prevents silent disconnects +5. **Profile & calibration settings** — age/sex/height/weight, BP cuff reference, glucose offset +6. **Colmi-aware UI** — hides BP/BS panels and profile form for Colmi rings +7. **Vitals detail screens** — period selector, trend charts, stat tiles, threshold bars +8. **Threshold bars on all vitals panels** — color-coded reference ranges +9. **Combined measurement button** — one-tap BP+SpO₂+stress+fatigue+BS with countdown +10. **Pull-to-refresh** — immediate ring sync from Today dashboard +11. **Reactive Room database** — Flow-based live data throughout the app +12. **Calibrated display pipeline** — offsets applied before UI rendering diff --git a/docs/project/architecture.md b/docs/project/architecture.md new file mode 100644 index 0000000..0b0399f --- /dev/null +++ b/docs/project/architecture.md @@ -0,0 +1,75 @@ +--- +title: Architecture +description: How data flows from the ring into local storage and out to the AI coach. +--- + +# Architecture + +PulseLoop is built **local-first**: data flows up from the ring into local +storage on your phone, the coach reads sideways through tools, and the only thing +that ever leaves the device is a coach question you explicitly choose to ask. + +## System architecture + +Four layers on the phone. Data flows up from the ring into local storage; the +coach reads sideways through tools, and the only thing that leaves the device is a +coach question you choose to ask. + +![System architecture](../images/system-architecture.png) + +## The ring link + +One custom BLE service, fixed 20-byte cleartext packets, commands out and +notifications back. + +![Ring interaction](../images/ble-interaction.png) + +## The AI coach + +An agentic loop that calls tools to read your local data, then answers in a +structured format. Every answer is grounded in your actual ring data. + +![AI coach design](../images/AI-coach-design.png) + +## iOS project layout + +```text +PulseLoop/ +├─ RingProtocol/ BLE client + packet decoding for the ring +├─ Models/ SwiftData models (vitals, sleep, activity, coach) +├─ Services/ Sync, workouts, GPS, derived summaries +├─ Coach/ The LLM coach: orchestration, tools, prompts, notifications +│ ├─ Orchestration/ Agentic turn loop, tool execution, fallbacks +│ ├─ Tools/ Retrieval, analysis, charts, memory, web search, actions +│ ├─ OpenAI/ Responses API client +│ ├─ Gemini/ Google Gemini client +│ └─ Notifications/ Daily AI check-ins +├─ Views/ SwiftUI screens (Today, Vitals, Sleep, Activity, Coach) +└─ DesignSystem/ Charts, components, theming + +PulseLoopLiveActivity/ Live Activity + Dynamic Island widget +PulseLoopTests/ Unit tests +``` + +## Same data flow, two stacks + +Both ports map the same data flow onto their native platform stack. The ring +protocol layer is the shared core; everything above it is platform-native. + +| Layer | iOS | Android | +|-------|-----|---------| +| UI | SwiftUI | Jetpack Compose + Material 3 | +| Persistence | SwiftData | Room (SQLite) | +| BLE | CoreBluetooth | `android.bluetooth.le` | +| HTTP | URLSession | OkHttp | +| Key storage | Keychain | EncryptedSharedPreferences | +| Background work | BGTaskScheduler | WorkManager | +| Live Activity | WidgetKit / Dynamic Island | ForegroundService + notification | +| Charts | Swift Charts | Custom Compose Canvas | +| Maps | MapKit | Canvas polyline | +| Event bus | NotificationCenter | SharedFlow | +| Notifications | UNUserNotificationCenter | NotificationManager + WorkManager | + +For the full feature-level breakdown between the two ports, see +[iOS vs Android](../platforms/ios-vs-android.md). For the on-the-wire ring +protocol, see [Supported Rings](../hardware/index.md). diff --git a/docs/project/contributing.md b/docs/project/contributing.md new file mode 100644 index 0000000..b1e4e06 --- /dev/null +++ b/docs/project/contributing.md @@ -0,0 +1,127 @@ +--- +title: Contributing +description: How to get set up, the standards PRs are held to, and how to add a new ring. +--- + +# Contributing + +Thank you! PulseLoop is an open, privacy-first health app that turns a cheap +Bluetooth ring into a real, local-first health tracker. Contributions of all +kinds are welcome — bug reports, new ring drivers, coach improvements, UI polish, +and docs. + +!!! tip "Start in the Discord" + The fastest way to get unstuck, claim an issue, or coordinate cross-platform + work is the [PulseLoop Discord](https://discord.gg/t9y85ebaKD). For anything + large, open an issue to discuss the approach **before** writing a lot of code. + +This page summarizes the workflow. The authoritative version lives in each repo: + +- iOS: [`CONTRIBUTING.md`](https://github.com/saksham2001/PulseLoopiOS/blob/main/CONTRIBUTING.md) + and [`CODE_OF_CONDUCT.md`](https://github.com/saksham2001/PulseLoopiOS/blob/main/CODE_OF_CONDUCT.md) +- Android: [PulseLoopAndroid](https://github.com/foureight84/PulseLoopAndroid) + +## Code of conduct + +This project follows a +[Code of Conduct](https://github.com/saksham2001/PulseLoopiOS/blob/main/CODE_OF_CONDUCT.md). +By participating, you're expected to uphold it. Please be kind. + +## Ways to contribute + +- **Report a bug** — open a [bug report](https://github.com/saksham2001/PulseLoopiOS/issues/new?template=bug_report.yml). +- **Request a feature** — open a [feature request](https://github.com/saksham2001/PulseLoopiOS/issues/new?template=feature_request.yml). +- **Add a wearable** — open a [new wearable support](https://github.com/saksham2001/PulseLoopiOS/issues/new?template=new_wearable_support.yml) + issue, ideally with BLE service/characteristic UUIDs and packet captures. +- **Send a pull request** — see below. + +## Development setup (iOS) + +**Requirements** + +- macOS with **Xcode 16+**. +- An **iOS 18+ physical device** for anything touching Bluetooth or Live + Activities — the simulator cannot reach the ring. +- A compatible BLE ring (see [supported rings](../hardware/index.md)), + or use demo data if you don't have hardware. +- An OpenAI/Gemini API key only if you're working on the Coach. + +See [Getting Started on iOS](../getting-started/ios.md) for full build steps, and +[Getting Started on Android](../getting-started/android.md) for the Android flow. + +## Running the tests (iOS) + +The unit tests in `PulseLoopTests/` are **hermetic** — in-memory SwiftData and a +mocked client (`sk-test`), so they need no network and no secrets. + +- In Xcode: `⌘U`. +- From the CLI: + + ```sh + xcodebuild test \ + -project PulseLoop.xcodeproj \ + -scheme PulseLoop \ + -destination 'platform=iOS Simulator,name=iPhone 16' + ``` + +CI runs this exact suite on every PR. **Please add or update tests** for any +behavior you change — especially decoders, capability gating, sleep/activity +math, and coach tools. + +## Code style (iOS) + +- We use **SwiftLint** (config in `.swiftlint.yml`); CI runs it on every PR. + Install locally with `brew install swiftlint` and run `swiftlint` from the repo + root. +- Match the surrounding code: SwiftUI views in `Views/`, models in `Models/`, etc. + Keep changes small and focused. +- Prefer clarity over cleverness. Comments should explain *why*, not *what*. + +## Adding support for a new wearable + +PulseLoop has a **device-agnostic driver layer** (`RingProtocol/` on iOS). Each +device declares the capabilities it supports, and the UI shows only those +features. To add a ring: + +1. **Identify it** — advertised BLE name, primary service UUID, and the + write/notify characteristic UUIDs (use a scanner like LightBlue or nRF Connect). +2. **Decode the protocol** — capture the 20-byte command/notification packets from + the vendor app and map them to metrics. Existing decoders (`RingDecoderTests`, + `ColmiDecoderTests`) are good references and good places to add coverage. +3. **Declare capabilities** — give the driver the right capability set so the app + gates features correctly. +4. **Add tests** — decoder round-trips and capability gating, following the + existing test files. +5. **Update the capability matrix** — add the new model and its support status + (here and in the [Supported Rings](../hardware/index.md) page). + +You don't need the hardware to *start* — a good packet capture in an issue lets +others help. Mark anything you couldn't verify on real hardware as 🧪 +("implemented, needs testing"). + +## Pull request process + +1. **Fork** the repo and create a branch from `main`: + `git checkout -b feature/short-description`. +2. Make your change, **add tests**, and make sure lint and the test suite pass + locally. +3. **Open a PR** against `main` and fill out the PR template. Link any related + issue (`Closes #123`). +4. **CI must be green** — build, tests, and SwiftLint all pass. +5. **Review** — the maintainer reviews and may request changes. One approving + review is required to merge. +6. Once approved and green, your PR gets merged. 🎉 + +Keep PRs focused — one logical change per PR is much easier to review. + +!!! warning "Privacy expectations" + PulseLoop's promise is that **your health data stays on your device**. Any PR + that changes what data leaves the device, or how it's stored, must call that + out clearly in the PR description and will get extra scrutiny. Never commit + secrets, API keys, or real personal health data. See [Privacy](privacy.md). + +## License + +By contributing, you agree that your contributions will be licensed under the +project's [CC BY 4.0](https://github.com/saksham2001/PulseLoopiOS/blob/main/LICENSE) +license. diff --git a/docs/project/privacy.md b/docs/project/privacy.md new file mode 100644 index 0000000..4f341fc --- /dev/null +++ b/docs/project/privacy.md @@ -0,0 +1,32 @@ +--- +title: Privacy +description: PulseLoop is local-first by design — what leaves your device and what never does. +--- + +# Privacy + +PulseLoop is built **local-first**, which is the whole point. + +- **No vendor cloud, no account.** The app talks to the ring directly over + Bluetooth LE. +- **Your data stays on your phone**, persisted locally (SwiftData on iOS, Room on + Android). +- **AI Coach is off by default and optional.** You can use the app without it; it + is disabled by default in Settings. +- **Nothing leaves the device** except a coach question you explicitly ask — that + single request goes to whichever LLM provider you configured, with the API key + you supply. +- **API keys are stored securely on-device** — the iOS Keychain, or Android's + `EncryptedSharedPreferences`. + +!!! warning "Not a medical device" + PulseLoop is not a medical device and is not a substitute for professional + medical advice. Treat all readings as approximate. Always consult a clinician + for health concerns. + +## For contributors + +The promise that your health data stays on your device is a hard constraint. Any +change that affects what data leaves the phone, or how it's stored, must be called +out clearly in the PR description and will get extra scrutiny. Never commit +secrets, API keys, or real personal health data. See [Contributing](contributing.md). diff --git a/docs/project/roadmap.md b/docs/project/roadmap.md new file mode 100644 index 0000000..1aa98bf --- /dev/null +++ b/docs/project/roadmap.md @@ -0,0 +1,89 @@ +--- +title: Roadmap +description: Long-term direction and guiding principles for PulseLoop, across both the iOS and Android ports. +--- + +# Roadmap + +!!! tip "Where live planning happens" + Up-to-date plans and what's shipping next live in the + [Releases](https://github.com/saksham2001/PulseLoopiOS/releases) and the + [Discord](https://discord.gg/t9y85ebaKD). This page captures the long-term + direction shared across the project. + +## Principles + +These guide what we build and what we say no to. + +- **Privacy-first**: your health data stays on your device by default. +- **Subscription-free**: every feature, for everyone, no paywalls. +- **Open & transparent**: documented metrics and an auditable coach, no black boxes. +- **Hardware freedom**: cheap devices, your data, and eventually your own firmware. +- **Cross-platform**: one direction shared across iOS and Android. + +## Direction + +### More wearables, more freedom + +- **Open BLE standards**: heart rate (+ HRV), blood pressure, temperature, weight, + and glucose. Supporting the standards adds chest straps, BP cuffs, and scales with + little per-device work. +- **Reverse-engineered protocols**: more rings (Ultrahuman, RingConn, …) and + bands/watches (Amazfit/Zepp, Xiaomi) beyond today's `56ff` and Colmi families. +- **Device-driver SDK**: let contributors add a wearable without touching the core. + +### Own the hardware + +- Reverse-engineer ring firmware and the over-the-air update path. +- Load custom firmware safely: higher sampling rates, longer battery, and access + the stock app blocks. +- Unlock **raw PPG and accelerometer** signals: the basis for everything intelligent. + +### On-device intelligence + +- **Local LLM coach**: run against an on-device model: no API key, no network, full privacy. +- **Automatic workout detection**: recognize runs, rides, and walks with no manual start. +- **Proactive insights**: weekly trends and call-outs the coach surfaces for you. +- **Auditable coach**: show which tools the coach called and what data it read. +- **Personal baselines**: learn what's normal for you and flag meaningful changes. + +### Metrics you can trust + +- **Performance & recovery**: readiness, training/cardio load, HRV and resting-HR + trends, VO₂max. +- **Health signals**: illness early-warning from shifts in skin temperature, resting + heart rate, and respiration. +- **Cycle tracking**: menstrual cycle and BBT from skin temperature, computed on-device. +- **Energy balance**: calorie-burn estimation paired with food logging via an open + food database. + +### Your data, your way + +- **Optional sync**: Apple Health, Google Health Connect, Strava, Garmin; useful for + export and for cross-checking your readings. +- **Self-hosted export**: Home Assistant, InfluxDB/Grafana, MQTT, and open formats + (FIT, GPX, CSV, JSON). +- **Ownership by default**: your data is portable and never required to leave the device. + +### Everywhere you are + +- **Multiple wearables at once**: aggregate several devices into one picture. +- **watchOS companion**: glanceable data, or use a watch as another sensor. +- **Web app**: a third client alongside iOS and Android. + +## Cross-platform parity + +Because the iOS and Android ports share the same protocol work, a big part of the +roadmap is simply bringing the two ports to feature parity. The Android build is +currently ahead in several areas (fuller protocol decoding, calibration, +connection reliability, richer vitals UI). + +See [iOS vs Android](../platforms/ios-vs-android.md) for the current gap list - +much of it is fair game for contributors who want a well-scoped first task. + +## Want to help? + +- Skim the [open issues](https://github.com/saksham2001/PulseLoopiOS/issues), + especially anything tagged **good first issue**. +- Propose or claim work in the [Discord](https://discord.gg/t9y85ebaKD). Coordinate anything that should land on both platforms. +- See [Contributing](contributing.md) to get set up. \ No newline at end of file diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..b8c5a58 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,125 @@ +/* =========================================================================== + PulseLoop brand polish for MkDocs Material. + Palette pulled from icon-source.svg + the app's DesignSystem: + violet #7C5CFF / #863bff / #7e14ff + lavender #EDE6FF / #D2CDFF / #8B7CFF + cyan #47BFFF / #2DD4D8 + slate #0E1118 / #080A0F / #0F141F + =========================================================================== */ + +:root { + --pl-violet: #7c5cff; + --pl-violet-deep: #5b3df0; + --pl-lavender: #d2cdff; + --pl-cyan: #47bfff; + --pl-cyan-deep: #2dd4d8; + --pl-ink: #0e1118; + --pl-ink-deep: #080a0f; +} + +/* Brand the primary + accent across both schemes. */ +[data-md-color-primary="deep-purple"] { + --md-primary-fg-color: var(--pl-violet); + --md-primary-fg-color--light: #8b7cff; + --md-primary-fg-color--dark: var(--pl-violet-deep); +} +[data-md-color-accent="cyan"] { + --md-accent-fg-color: var(--pl-cyan); +} + +/* A soft violet→cyan glow on the top header, on both schemes. */ +.md-header { + background-image: linear-gradient( + 100deg, + var(--pl-violet-deep) 0%, + var(--pl-violet) 45%, + var(--pl-cyan) 130% + ); +} +.md-tabs { + background: transparent; +} + +/* Larger brand mark in the top navbar (Material defaults to 1.2rem). */ +.md-header__button.md-logo { + padding: 0.2rem; +} +.md-header__button.md-logo img, +.md-header__button.md-logo svg { + height: 2.2rem; + width: 2.2rem; +} + +/* ---- Dark scheme: lean into the "glow on slate" brand feel. ---- */ +[data-md-color-scheme="slate"] { + --md-default-bg-color: var(--pl-ink); + --md-default-bg-color--light: #11151f; + --md-typeset-a-color: var(--pl-lavender); + --md-footer-bg-color: var(--pl-ink-deep); +} + +/* Radial violet glow behind the main content, top-center — echoes the icon. */ +[data-md-color-scheme="slate"] .md-main { + background: + radial-gradient( + 900px 420px at 50% -8%, + rgba(124, 92, 255, 0.16), + transparent 70% + ), + var(--md-default-bg-color); +} + +/* Links: lavender by default, cyan on hover. */ +.md-typeset a { + text-decoration-color: rgba(124, 92, 255, 0.4); +} +.md-typeset a:hover { + color: var(--pl-cyan); +} + +/* =========================================================================== + Home page "choose your platform" grid cards (attr_list + md_in_html). + Usage in markdown: wrap cards in
...
+ Material already ships .grid.cards; this just adds PulseLoop flavor. + =========================================================================== */ +.md-typeset .grid.cards > :is(ul, ol) > li, +.md-typeset .grid.cards > .card { + border: 1px solid rgba(124, 92, 255, 0.25); + border-radius: 0.6rem; + transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; +} +.md-typeset .grid.cards > :is(ul, ol) > li:hover, +.md-typeset .grid.cards > .card:hover { + border-color: var(--pl-violet); + box-shadow: 0 8px 28px rgba(124, 92, 255, 0.22); + transform: translateY(-2px); +} + +/* Hero block on the landing page. */ +.pl-hero { + text-align: center; + padding: 1.2rem 0 0.4rem; +} +.pl-hero h1 { + font-weight: 800; + letter-spacing: -0.02em; + background: linear-gradient(92deg, var(--pl-lavender), var(--pl-cyan)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} +.pl-hero .pl-tagline { + font-size: 1.05rem; + opacity: 0.85; + max-width: 46rem; + margin: 0.2rem auto 1rem; +} + +/* Buttons (Material .md-button) in a centered row for the hero CTAs. */ +.pl-cta { + display: flex; + flex-wrap: wrap; + gap: 0.6rem; + justify-content: center; + margin: 0.6rem 0 1.4rem; +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..bd32c0a --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,120 @@ +site_name: PulseLoop +site_description: >- + An LLM-native, local-first health app that turns a cheap Bluetooth smart ring + into a real, conversational health tracker — on iOS and Android. +site_author: Saksham Bhutani +# TODO: set this to your real GitHub Pages URL once Pages is enabled. +# For a project site this is https://.github.io// +site_url: https://saksham2001.github.io/PulseLoopiOS/ + +repo_name: saksham2001/PulseLoopiOS +repo_url: https://github.com/saksham2001/PulseLoopiOS +edit_uri: edit/main/docs/ + +copyright: >- + Copyright © 2026 Saksham Bhutani — PulseLoop is licensed under CC BY 4.0. + +theme: + name: material + language: en + logo: assets/logo.svg + favicon: assets/logo.svg + icon: + repo: fontawesome/brands/github + font: + text: Inter + code: JetBrains Mono + palette: + # Dark is the brand default (glow on slate). + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: deep purple + accent: cyan + toggle: + icon: material/brightness-4 + name: Switch to light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: deep purple + accent: cyan + toggle: + icon: material/brightness-7 + name: Switch to dark mode + features: + - navigation.tabs + - navigation.tabs.sticky + - navigation.sections + - navigation.top + - navigation.instant + - navigation.instant.progress + - navigation.footer + - navigation.indexes + - content.code.copy + - content.tabs.link + - search.suggest + - search.highlight + - search.share + - toc.follow + +extra_css: + - stylesheets/extra.css + +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - tables + - toc: + permalink: true + - pymdownx.details + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + +plugins: + - search + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/saksham2001/PulseLoopiOS + name: PulseLoop on iOS (GitHub) + - icon: fontawesome/brands/android + link: https://github.com/foureight84/PulseLoopAndroid + name: PulseLoop on Android (GitHub) + - icon: fontawesome/brands/discord + link: https://discord.gg/t9y85ebaKD + name: Join the PulseLoop Discord + +nav: + - Home: index.md + - Getting Started: + - iOS: getting-started/ios.md + - Android: getting-started/android.md + - Hardware: + - Overview: hardware/index.md + - Jring / 56ff: hardware/jring.md + - Colmi / Yawell: hardware/colmi.md + - SIMSONLAB: hardware/simsonlab.md + - Premium Rings: hardware/premium.md + - Platforms: + - iOS vs Android: platforms/ios-vs-android.md + - Project: + - Roadmap: project/roadmap.md + - Architecture: project/architecture.md + - Contributing: project/contributing.md + - Privacy: project/privacy.md diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 0000000..0b9684a --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,3 @@ +# Documentation site dependencies (MkDocs Material). +# Build locally with: pip install -r requirements-docs.txt && mkdocs serve +mkdocs-material>=9.5 From 864ff50ef5488670f0f5beb396986543721949f6 Mon Sep 17 00:00:00 2001 From: Saksham Bhutani Date: Sun, 28 Jun 2026 04:15:06 -0400 Subject: [PATCH 2/5] removed redundant info from the README --- README.md | 167 +++++++++++++----------------------------------------- 1 file changed, 38 insertions(+), 129 deletions(-) diff --git a/README.md b/README.md index 5809845..62c97b7 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Platform Swift License + Docs Discord

@@ -22,6 +23,7 @@

+ 📚 Documentation · 📱 Now on Android · 💬 Join the Discord · 📖 Read the writeup @@ -58,6 +60,7 @@ your sleep, heart rate, activity, and recovery. ## Contents +- [Documentation](#documentation) - [What it does](#what-it-does) - [Also on Android](#also-on-android) - [Community](#community) @@ -66,13 +69,23 @@ your sleep, heart rate, activity, and recovery. - [Install & try it](#install--try-it) - [Privacy](#privacy) - [Contributing](#contributing) -- [Goals / Roadmap](#goals--roadmap) -- [Project layout](#project-layout) - [Acknowledgements](#acknowledgements) - [License](#license) --- +## Documentation + +📚 **Full docs: [saksham2001.github.io/PulseLoopiOS](https://saksham2001.github.io/PulseLoopiOS/)** + +- [Getting started — iOS](https://saksham2001.github.io/PulseLoopiOS/getting-started/ios/) +- [Getting started — Android](https://saksham2001.github.io/PulseLoopiOS/getting-started/android/) +- [Supported hardware](https://saksham2001.github.io/PulseLoopiOS/hardware/) +- [iOS vs Android](https://saksham2001.github.io/PulseLoopiOS/platforms/ios-vs-android/) +- [Architecture](https://saksham2001.github.io/PulseLoopiOS/project/architecture/) · [Roadmap](https://saksham2001.github.io/PulseLoopiOS/project/roadmap/) · [Contributing](https://saksham2001.github.io/PulseLoopiOS/project/contributing/) + +--- + ## What it does - **Connects to the ring over BLE** and decodes its proprietary protocol @@ -144,74 +157,26 @@ New here? Good places to start: > your own risk and treat any data the ring produces as approximate. PulseLoop is built around a device-agnostic driver layer, so each supported ring -declares exactly what it can do and the app shows only those features. The -tables below break support down by capability. - -**Support status legend** - -| Status | Meaning | -| --- | --- | -| ✅ | **Supported & tested**: Fully verified working on real hardware | -| 🧪 | **Implemented, needs testing**: code is in place (decoded from the protocol) but not yet tested with that specific model | -| 🚧 | **Planned / not yet implemented** | -| — | **Not applicable**: the hardware doesn't expose this capability | +declares exactly what it can do and the app shows only those features. -### Ring families - -| Ring | BLE Family | Advertised name | Price | Listing | -| --- | --- | --- | --- | --- | -| jring (generic smart ring) | `56ff` | `SMART_RING` | $7–12 | [AliExpress](https://www.aliexpress.us/item/3256810466598469.html) | -| Colmi / Yawell ring family | `6e40fff0` / `de5bf728` | `R02_…`, `R0x…`, `COLMI R1x…`, `H59_…` | $15–30 | [Colmi store](https://www.colmi.com/) | - -### Capability matrix - -Major functional areas, by device: - -| Capability | jring | Colmi R11 | Other Colmi/Yawell¹ | +| Ring | BLE Family | Advertised name | Price | | --- | --- | --- | --- | -| **Connection & pairing** (scan, connect, reconnect, forget) | ✅ | ✅ | 🧪 | -| **History sync** (pull stored data on connect) | ✅ | ✅ | 🧪 | -| **Heart rate — spot measurement** | ✅ | ✅ | 🧪 | -| **Heart rate — history** | ✅ | ✅ | 🧪 | -| **Heart rate — live (workout)** | ✅ | ✅ | 🧪 | -| **SpO₂ — spot measurement** | ✅ | — ² | — ² | -| **SpO₂ — history** | ✅ | ✅ | 🧪 | -| **Steps / distance / calories** | ✅ | ✅ ³ | 🧪 | -| **Activity / workout recording** (live HR, zones, GPS route) | ✅ | ✅ | 🧪 | -| **Sleep stages** (light / deep / awake) | ✅ | ✅ | 🧪 | -| **REM sleep** | — | ✅ | 🧪 | -| **HRV** | — | ✅ | 🧪 | -| **Stress** | — | ✅ | 🧪 | -| **Body temperature** | — | ✅ | 🧪 | -| **Battery level** | ✅ | ✅ | 🧪 | -| **Find device** | ✅ | ✅ | 🧪 | - -¹ Other Colmi/Yawell models recognized by the same driver: **Colmi R02, R03, -R06, R07, R09, R10, R12** and **Yawell R05, R10, R11, H59**. Same protocol as -the R11, so all capabilities are implemented, but not yet hardware-verified -per model. - -² The Colmi family has no on-demand SpO₂ reading; SpO₂ is an all-day background -metric, so only the synced **history/graph** is available (no spot button). - -³ Calories from Colmi history are currently hidden pending verification of the -raw value; steps and distance are shown. +| jring (generic smart ring) | `56ff` | `SMART_RING` | $7–12 | +| Colmi / Yawell ring family | `6e40fff0` / `de5bf728` | `R02_…`, `R0x…`, `COLMI R1x…`, `H59_…` | $15–30 | + +> 📚 **Full hardware specs, per-model capability matrix, and buying guidance: +> [Supported hardware docs](https://saksham2001.github.io/PulseLoopiOS/hardware/).** --- ## How it works -**System architecture:** four layers on the phone. Data flows up from the ring into local storage; the coach reads sideways through tools, and the only thing that leaves the device is a coach question you choose to ask. - -[![System architecture](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/system-architecture.png)](/docs/images/system-architecture.png) +- **System architecture:** four layers on the phone. Data flows up from the ring into local storage; the coach reads sideways through tools, and the only thing that leaves the device is a coach question you choose to ask. +- **The ring link:** one custom BLE service, fixed 20-byte cleartext packets, commands out and notifications back. +- **The AI coach:** an agentic loop that calls tools to read your local data, then answers in a structured format. -**The ring link:** one custom BLE service, fixed 20-byte cleartext packets, commands out and notifications back. - -[![Ring interaction](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/ble-interaction.png)](/docs/images/ble-interaction.png) - -**The AI coach:** an agentic loop that calls tools to read your local data, then answers in a structured format. - -[![AI coach](https://github.com/saksham2001/PulseLoopiOS/raw/main/docs/images/AI-coach-design.png)](/docs/images/AI-coach-design.png) +> 📚 **Diagrams and a full walkthrough: +> [Architecture docs](https://saksham2001.github.io/PulseLoopiOS/project/architecture/).** --- @@ -224,30 +189,15 @@ A public TestFlight beta is coming soon. Sign up on the ### 🛠️ Build from source (Xcode) -**Requirements** - -- Xcode 16+ and an iOS 18+ device (Bluetooth and Live Activities need a real -device — the simulator can't reach the ring). -- A compatible `56ff` or Colmi/Yawell BLE ring. -- An OpenAI or Gemini API key (for the Coach features). - -**Run it** - -1. Open `PulseLoop.xcodeproj` in Xcode. -2. Select the `PulseLoop` scheme and your physical device as the run target. -3. Set your own **Team** and a unique **Bundle Identifier** under -*Signing & Capabilities* (the Live Activity extension target needs this too). -4. Build & run (`⌘R`). -5. On first launch, complete onboarding, then keep the ring nearby — the app -auto-scans and connects when Bluetooth powers on. -6. To enable the Coach, open **Settings → Coach** and paste your API key. It's -stored in the iOS Keychain and never leaves the device except to call the model. -Pick a provider and model. +You'll need Xcode 16+, an iOS 18+ device, a compatible `56ff` or Colmi/Yawell +ring, and (optionally) an OpenAI or Gemini API key for the Coach. Open +`PulseLoop.xcodeproj`, set your **Team** + a unique **Bundle Identifier**, then +build & run on your device. -**Demo data (no ring required)** - -You can explore the UI without hardware: **Settings → "Reseed demo data"**, or -launch with the `-seedDemo YES` argument. +> 📚 **Full step-by-step build, signing, and demo-data instructions: +> [Getting started — iOS](https://saksham2001.github.io/PulseLoopiOS/getting-started/ios/).** +> Building on Android? See the +> [Android guide](https://saksham2001.github.io/PulseLoopiOS/getting-started/android/). --- @@ -285,50 +235,9 @@ that should land on Android too. Adding a new ring? The device-agnostic driver layer in `RingProtocol/` is the place to start — ping us in Discord and we'll point you at the right files. ---- - -## Goals / Roadmap - -> Up-to-date plans and what's shipping next now live in the -> [Releases](https://github.com/saksham2001/PulseLoopiOS/releases) and the -> [Discord](#community). High-level direction: - -- [ ] **On-device LLM integration** — run the coach against a local model -(Apple Foundation Models / a quantized on-device LLM) so the app works with -no API key, no network, and full privacy. -- [ ] **Support more cheap rings and other wearables** — generalize the BLE protocol layer to -handle other low-cost ring families beyond the `56ff` devices. -- [ ] **Custom ring firmware** — open firmware to unlock features the stock -ring won't do, e.g. automatic activity/workout detection, higher-rate -sampling, and richer sensor access. -- [ ] **Better onboarding** — smoother first-run pairing, permission, and -setup journey. -- [ ] **LLM tool-call transparency** — surface exactly which tools the coach -called and what data it read, so every answer is auditable. -- [ ] **Multimodal coach input** — let the coach accept image and voice input (e.g. snap a meal, speak a question). -- [ ] **Apple Health integration** — sync data with Apple Health. - ---- - -## Project layout - -``` -PulseLoop/ -├─ RingProtocol/ BLE client + packet decoding for the ring -├─ Models/ SwiftData models (vitals, sleep, activity, coach) -├─ Services/ Sync, workouts, GPS, derived summaries -├─ Coach/ The LLM coach: orchestration, tools, prompts, notifications -│ ├─ Orchestration/ Agentic turn loop, tool execution, fallbacks -│ ├─ Tools/ Retrieval, analysis, charts, memory, web search, actions -│ ├─ OpenAI/ Responses API client -│ ├─ Gemini/ Google Gemini client -│ └─ Notifications/ Daily AI check-ins -├─ Views/ SwiftUI screens (Today, Vitals, Sleep, Activity, Coach) -└─ DesignSystem/ Charts, components, theming - -PulseLoopLiveActivity/ Live Activity + Dynamic Island widget -PulseLoopTests/ Unit tests -``` +> 📚 The [roadmap](https://saksham2001.github.io/PulseLoopiOS/project/roadmap/) and +> [architecture / project layout](https://saksham2001.github.io/PulseLoopiOS/project/architecture/) +> now live in the docs. --- From 88ec6a5155d37b33054593e4164edcf2287e74f0 Mon Sep 17 00:00:00 2001 From: Saksham Bhutani Date: Sun, 28 Jun 2026 04:22:32 -0400 Subject: [PATCH 3/5] README cleanup --- README.md | 53 +++++------------------------------------------------ 1 file changed, 5 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 62c97b7..7fbf5ee 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@

- - PulseLoop + + PulseLoop

@@ -58,22 +58,6 @@ your sleep, heart rate, activity, and recovery. --- -## Contents - -- [Documentation](#documentation) -- [What it does](#what-it-does) -- [Also on Android](#also-on-android) -- [Community](#community) -- [Supported wearables](#supported-wearables) -- [How it works](#how-it-works) -- [Install & try it](#install--try-it) -- [Privacy](#privacy) -- [Contributing](#contributing) -- [Acknowledgements](#acknowledgements) -- [License](#license) - ---- - ## Documentation 📚 **Full docs: [saksham2001.github.io/PulseLoopiOS](https://saksham2001.github.io/PulseLoopiOS/)** @@ -99,7 +83,9 @@ search. Every answer is grounded in your actual ring data. Activity, and a Dynamic Island widget. - **Daily check-in notifications** generated by the coach from your recent trends. -- **Metric & imperial units** and a fully reworked settings pane. + +> 📚 **Diagrams and a full walkthrough: +> [Architecture docs](https://saksham2001.github.io/PulseLoopiOS/project/architecture/).** ### Screenshots @@ -169,17 +155,6 @@ declares exactly what it can do and the app shows only those features. --- -## How it works - -- **System architecture:** four layers on the phone. Data flows up from the ring into local storage; the coach reads sideways through tools, and the only thing that leaves the device is a coach question you choose to ask. -- **The ring link:** one custom BLE service, fixed 20-byte cleartext packets, commands out and notifications back. -- **The AI coach:** an agentic loop that calls tools to read your local data, then answers in a structured format. - -> 📚 **Diagrams and a full walkthrough: -> [Architecture docs](https://saksham2001.github.io/PulseLoopiOS/project/architecture/).** - ---- - ## Install & try it ### 📲 TestFlight beta @@ -201,24 +176,6 @@ build & run on your device. --- -## Privacy - -PulseLoop is built local-first, which is the whole point: - -- **No vendor cloud, no account.** The app talks to the ring directly over BLE. -- **Your data stays on your phone**, persisted locally with SwiftData. -- **AI Coach is off by default and optional.** You can use the app without it, and it is disabled by default in the settings. -- **Nothing leaves the device** except a coach question you explicitly ask — -that single request goes to whichever LLM provider you configured, with the API -key you supply. -- **API keys live in the iOS Keychain.** - -> ⚠️ PulseLoop is not a medical device and is not a substitute for professional -> medical advice. Treat all readings as approximate. Always consult a clinician -> for health concerns. - ---- - ## Contributing PRs and issues are very welcome — this project moves fast because people pitch From a0ce2ee372b2087a80009d8dd32ae7a8b61eecb9 Mon Sep 17 00:00:00 2001 From: Saksham Bhutani Date: Sun, 28 Jun 2026 04:26:55 -0400 Subject: [PATCH 4/5] README cleanup --- README.md | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/README.md b/README.md index 7fbf5ee..3450fd7 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,6 @@ X post

---- - An LLM-native health app for iOS that turns a cheap Bluetooth "smart ring" into a real, conversational health tracker. It currently supports the generic Chinese Jring and the Colmi / Yawell ring family (R02/R0x/R1x/H59), behind a device-agnostic driver layer so @@ -56,8 +54,6 @@ your sleep, heart rate, activity, and recovery. > wearable, and that the "intelligence" should live on the phone, not behind a > paywall. ---- - ## Documentation 📚 **Full docs: [saksham2001.github.io/PulseLoopiOS](https://saksham2001.github.io/PulseLoopiOS/)** @@ -68,8 +64,6 @@ your sleep, heart rate, activity, and recovery. - [iOS vs Android](https://saksham2001.github.io/PulseLoopiOS/platforms/ios-vs-android/) - [Architecture](https://saksham2001.github.io/PulseLoopiOS/project/architecture/) · [Roadmap](https://saksham2001.github.io/PulseLoopiOS/project/roadmap/) · [Contributing](https://saksham2001.github.io/PulseLoopiOS/project/contributing/) ---- - ## What it does - **Connects to the ring over BLE** and decodes its proprietary protocol @@ -97,8 +91,6 @@ trends. | --- | --- | --- | | [![Activity](https://github.com/saksham2001/PulseLoopiOS/raw/main/screenshots/activity%20page%201.PNG)](/screenshots/activity%20page%201.PNG) | [![Vitals](https://github.com/saksham2001/PulseLoopiOS/raw/main/screenshots/vitals%20page%201.PNG)](/screenshots/vitals%20page%201.PNG) | [![Workout Summary](https://github.com/saksham2001/PulseLoopiOS/raw/main/screenshots/activity%20recording-%20complete%201.PNG)](/screenshots/activity%20recording-%20complete%201.PNG) | ---- - ## Also on Android PulseLoop has a sister project for Android: **[PulseLoopAndroid](https://github.com/foureight84/PulseLoopAndroid)** @@ -112,8 +104,6 @@ Pick the build for your phone — both connect to the same rings. > Coordination, the shared roadmap, and cross-platform discussion all happen in > the [Discord](#community). ---- - ## Community We run a Discord for roadmap planning, getting-started help, and coordinating @@ -130,8 +120,6 @@ New here? Good places to start: - Say hi in Discord and tell us what ring you have — device reports are genuinely useful. ---- - ## Supported Wearables > **Disclaimer:** We have no affiliation with the sellers or manufacturers of @@ -153,8 +141,6 @@ declares exactly what it can do and the app shows only those features. > 📚 **Full hardware specs, per-model capability matrix, and buying guidance: > [Supported hardware docs](https://saksham2001.github.io/PulseLoopiOS/hardware/).** ---- - ## Install & try it ### 📲 TestFlight beta @@ -174,8 +160,6 @@ build & run on your device. > Building on Android? See the > [Android guide](https://saksham2001.github.io/PulseLoopiOS/getting-started/android/). ---- - ## Contributing PRs and issues are very welcome — this project moves fast because people pitch @@ -196,8 +180,6 @@ place to start — ping us in Discord and we'll point you at the right files. > [architecture / project layout](https://saksham2001.github.io/PulseLoopiOS/project/architecture/) > now live in the docs. ---- - ## Acknowledgements - [@foureight84](https://github.com/foureight84) for the @@ -205,8 +187,6 @@ place to start — ping us in Discord and we'll point you at the right files. - Everyone who's filed an issue, opened a PR, or reported a device — see the [contributors graph](https://github.com/saksham2001/PulseLoopiOS/graphs/contributors). ---- - ## License This project is licensed under [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://github.com/saksham2001/PulseLoopiOS/blob/main/LICENSE). From f4fdc5c5ff750eb259ecb63865dbdeb77f65fd4a Mon Sep 17 00:00:00 2001 From: Saksham Bhutani Date: Sun, 28 Jun 2026 04:29:39 -0400 Subject: [PATCH 5/5] fixed badge in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3450fd7..3572923 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Stars Forks Issues - PRs + PRs CI Platform