Skip to content

Releases: foureight84/PulseLoopAndroid

PulseLoop 2.8.0 (47)

PulseLoop 2.8.0 (47) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Sep 15:19

PulseLoop 2.8.0 (46)

PulseLoop 2.8.0 (46) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 08 Sep 18:02

PulseLoop 2.8.0 (45)

PulseLoop 2.8.0 (45) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Sep 04:46

Test build — rc5, follow-up to rc4. Prerelease. Fixes from a review pass over the branch, one of which matters if you already installed rc4 on a Colmi or CRP ring.

Please use this instead of rc4 on a Colmi / CRP ring

rc3 added a rule for the doubled readings on #60: the ring logs its own spot measurements, so when a later sync brings the ring's copy back, our row yields to it. That rule was correct for the ring it was built from, but it ran for every family — and Colmi and CRP rings record all-day heart rate and SpO₂ on a five-minute grid, where nothing is a copy of anything. A spot measurement taken within 90 seconds of one of those grid points would have been deleted in favour of it, which on a five-minute grid is most of them.

It is now gated at the point the reading is stored, to rings that actually report their own measurement completion. Every other ring stores a plain live reading exactly as it did before this branch, with nothing that can delete it. If you took spot measurements on rc4 with a Colmi or CRP ring and some are missing, that is this. Sorry.

Also fixed

  • The coach's "take a reading" tool reported the last raw sample the ring streamed rather than the settled reading, and wasn't cleared when a measurement failed — so a failed measurement could be reported as completed, with the pre-converged value #59 is about.
  • A ring ending its own workout session (a ring-side timeout, or stopping on the ring) no longer disables sport mode for every later workout on that connection. It ends that session; the next workout opens a fresh one. A ring that actually refuses sport mode is still remembered.
  • A SmartHealth-firmware ring named R100 <hex> would have matched the new R100 card and been given the wrong driver, connecting and then never syncing. The R100 pattern now only takes the _<hex> serial its reports actually show.
  • The delete confirmation now says "stays deleted the next time this day syncs" for Colmi stress and temperature readings too. It always behaved that way; it just wasn't saying so.

Testing

Everything asked for on rc4 still stands — @Albabit on the split-night total (#63), @aheider on the workout LED and heart-rate cadence (#64). @aheider, this build is the one to use: your R09 is one of the rings the reading-deletion bug above applied to.

PulseLoop 2.8.0 (44)

PulseLoop 2.8.0 (44) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Sep 01:07

Test build — rc4, follow-up to rc3. Prerelease, so the in-app updater won't offer it to anyone else. Everything confirmed on rc1–rc3 (#58, #59, #60) is unchanged.

Two new fixes, each from a fresh report against this branch.

#63 — a night the ring splits in two now keeps both halves

A YCBT ring closes a sleep session when you get up and opens a new one when you settle again, so a night can be two records a few minutes apart. PulseLoop merged them correctly the first time, then the next sync's copy of the second record wiped the first record's hours along with its own stale copy — 4 h 06 shown for a 6 h 08 night. A complete record now replaces only the stretch of stored sleep it actually describes; a neighbouring session across any gap is left alone. The sleep parser also resynchronises on each record's af fa header, so one bad length can't hide the sessions after it.

#64 — live workouts on Colmi rings run as a ring-side sport session

The QRing app doesn't use the realtime heart-rate commands during an activity at all. It puts the ring into sport mode (0x77) and the ring pushes its own telemetry (0x78, with heart rate) on its own cadence until the app ends the session — no timer, no keepalive. That is the near-constant LED and ~10 s readings QRing shows. PulseLoop was chaining one-shot spot measurements re-armed after 30 s of silence, which is the once-a-minute flash. Workouts now do what QRing does. If a ring refuses sport mode or stops pushing, the workout falls back to the previous behaviour rather than going blind.

What would help

  • @Albabit (#63) — a night's sleep, ideally one where you get up once. After the morning sync, and again after a second sync later in the day, the total should hold at the combined figure rather than dropping to the last session. Your ring read-back of the sessions is the ground truth to compare against.
  • @aheider (#64) — a live activity (cycling is fine) on the R09: does the green LED now stay on the way it does in QRing, and do heart-rate values land every ~10 s in the workout screen? A diagnostics export from Settings afterwards would show the 0x77/0x78 traffic and confirm the ring accepted sport mode.

PulseLoop 2.8.0 (43)

PulseLoop 2.8.0 (43) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Sep 19:24

Test build — rc3, follow-up to rc2. Prerelease, so the in-app updater won't offer it to anyone else. Everything confirmed working in rc1 and rc2 is unchanged.

Built from @Albabit's five SpO₂ captures and the ring-history read-back on #59, plus a review pass over the PR.

What changed

  • SpO₂ settles on the last plausible sample, because that is what the ring itself logs. Read back against the ring's own history, the last sample matched five runs out of five; the median matched four. The vendor app agrees: it shows each frame and re-reads history on 04 0e. Plausibility band 70–100, as the vendor uses.
  • The SpO₂ window is 75 s on this ring family. Every capture put 04 0e at t+63.1 s, three seconds after the old 60 s window gave up and fell back to settling on its own.
  • A spot reading the ring logs itself is no longer doubled. Our settled reading is stored, and when the next sync brings in the ring's own copy of that same measurement (same kind, within 90 s), ours yields to it. That is the 79/82 pair from rc1.
  • Intermediate samples can no longer slip past the one-reading rule while the storage side is catching up on a busy sync.
  • Blood pressure and HRV no longer treat the ring's success verdict as a failure (those legs read no value from 04 0e; the ring re-supplies it from history).
  • Diagnostics masking keeps the routing header for the R10M family too, not only TK5.

What would help

  • @Albabit — a few spot SpO₂ measurements: does the number now match what the Da Rings-side history stores for that run (your Python read-back is the ground truth here), and does the leg end on the ring's 04 0e rather than the window? Then a history sync afterwards: the reading should stay one row, and it should be the ring's.
  • @scufitarosie — nothing new is expected to change on the R100, but an install and a sync to confirm temperature, SpO₂ and the R100 card all still behave as on rc1 would rule out a regression before this merges.

PulseLoop 2.8.0 (42)

PulseLoop 2.8.0 (42) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Sep 20:58

Test build for @Albabit — rc2, follow-up to rc1. Prerelease, so the in-app updater won't offer it to anyone else. Everything confirmed working in rc1 is unchanged.

Built from your SpO₂ capture on #59. All three of the risks you flagged turned out not to apply — the SpO₂ leg used none of the machinery you were worried about — but the capture exposed a different problem underneath: the leg returned the first plausible sample and stopped, which on your run is 96 % at t+13 s, thirty-seven seconds before the ring finished and before nine further samples arrived.

What changed

  • SpO₂ now waits for the ring and settles the run, rather than answering on the first sample. It ends on 04 0e like heart rate does.
  • The settle takes the median. Your capture peaks at 99 and declines to 94, and one run can't say which end is honest — the median deliberately picks neither. This is provisional and marked as such in the code; more captures would settle it.
  • SpO₂ gets the one-reading-per-measurement rule that heart rate got in rc1. It matters more here: your run streams twelve values, all of which would otherwise land in your history.
  • The countdown is honest now. It sums only the legs your ring will actually run instead of all four, so it should read well under the 188 s you saw.

Rings that never send 04 0e (Colmi, CRP) keep the old fast path — waiting for a signal they don't send would just make their measurements a minute long for nothing.

What would help

  • Does a spot SpO₂ still land on a sensible number, and does it end when the ring does (~50 s) rather than running to the window?
  • Several more SpO₂ captures, if you're still willing. Whether the peak-then-decline shape is consistent is the one thing that would let me replace the median with a rule that's actually grounded.
  • Whether the doubled HR readings reappear. Best guess is that the ring logs the spot reading into its own history and a later sync imports it alongside ours — which would explain why a measurement with no sync after it gave you exactly one row. If you see it again, roughly when the last sync ran is the useful detail.

PulseLoop 2.8.0 (41)

PulseLoop 2.8.0 (41) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Sep 02:38

Test build for the reporters on #58, #59 and #60 — not a general release.

Flagged as a prerelease, so the in-app updater will not offer it to anyone else. Install pulseloop-2.8.0+41-universal.apk below over your current build; your data is kept (this includes a database migration to v24, which runs on first launch).

Everything here is from PR #62 and is untested on hardware — that is what this build is for.

What to try

#59 — spot heart rate (YCBT rings)
A measurement should now end when the ring says it is done (~35 s) rather than running the full window, and report a plausible number instead of the warm-up value. If it genuinely cannot read — ring loose, hand moving — it should still fail honestly rather than settle on something.

#60 — deleting readings
Open any vital from the Vitals screen and look for the new READINGS section under the stats. Each reading has a delete button and a confirmation. The part worth checking specifically: a reading that came from ring history should stay deleted after that same day syncs again.

Also relevant to #59: a failed measurement no longer writes a train of bogus readings into your history — only the settled result is stored.

#58 — R100 / CRP rings
The R100 should now appear as its own card in the pairing list. Temperature history should populate, including after ~18:00 — that part of the day was previously unreachable because the sync never advanced past the first frame.

If something is wrong

Settings → export diagnostics and attach it to the issue. The masking in this build keeps each frame's routing header, so a report now says which vital a frame belonged to — it will be considerably more useful than one from 2.7.0.

PulseLoop 2.7.0 (40)

Choose a tag to compare

@github-actions github-actions released this 30 Aug 20:45
fe1682b

What's Changed

  • fix(ring): restore the Android manufacturer-data match; fall back off 0x1E on RT-series firmware by @foureight84 in #57

Full Changelog: v2.7.0+39...v2.7.0+40

PulseLoop 2.7.0 (39)

Choose a tag to compare

@github-actions github-actions released this 24 Aug 01:05

Nutrition

  • Barcode scanner and AI meal analysis. Scan a packaged food's barcode or photograph a
    meal to log it, with an editable estimate before anything is saved.
  • Open Food Facts integration with a local product cache, so repeat lookups don't hit the
    network. The whole cache is now searched before falling back to the API.
  • Coach nutrition tools — search the food database, log, update, and delete meals from a
    conversation.
  • Meal confidence now defaults to "known", matching iOS, and existing rows are normalized on
    upgrade.

Coach

  • Self-hosted / local LLM providers honor a caller-supplied JSON schema, while keeping the
    coach's own response guidance intact on ordinary chat turns.
  • Coach notifications run a due slot as soon as a background sync completes, and a slot that
    falls back to a generic check-in is now recorded — so the same slot can't notify twice.

Rings

  • RWfit: the JieLi (0xAB) history path is complete — the 05-group bodies now decode.
  • Colmi R11 (CRP): driver hardening ported from iOS.

Workouts

  • Paused intervals are written to activity events, so a Strava TCX export drops paused
    trackpoints instead of drawing a straight line through them.

Fixes

  • Meal estimates with trailing prose after the JSON are parsed instead of rejected.
  • A malformed Open Food Facts base URL surfaces as a proper client error.

What's Changed

  • iOS sync: close the port queue (#93, #94, #96, #130, workout pause intervals) by @foureight84 in #53

Full Changelog: v2.7.0+38...v2.7.0+39

PulseLoop 2.7.0 (38)

Choose a tag to compare

@github-actions github-actions released this 22 Aug 18:03

What's Changed

  • fix: connecting no longer purges demo data at all (iOS parity)
  • feat(coach): local / self-hosted LLM provider with an optional API key

Full Changelog: v2.6.0+37...v2.7.0+38