Skip to content

Jring: offline BP/stress/sugar/HRV, SpO₂ and temperature history; calibration on the detail screens - #73

Merged
gabrielbr merged 4 commits into
mainfrom
ccr-67ccb970-dqwwqd
Nov 11, 2026
Merged

gabrielbr merged 4 commits into
mainfrom
ccr-67ccb970-dqwwqd

Conversation

@gabrielbr

@gabrielbr gabrielbr commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

Why

The owner asked whether the JRing app fakes BP and sugar. Reading the decompiled app (JRing 2.0.8, kept local and gitignored) answered it:

  • The app passes the ring's numbers through unchanged.
  • The ring computes BP and sugar from the user profile (0x02) and a cuff reference (0x33). The reference is write-only and defaults to 120/80.

The ring also keeps offline logs that we never read. The owner asked to:

  • import them, for trends;
  • keep sugar visible;
  • point users to calibration.

What

  • Offline history, per day after heart rate, in the vendor's order. Each log is asked for only when the ring's capability reply (0x20) sets the matching bit, as the vendor does.

    Log Request Gate Reply
    Skin temperature 39 <day> bit 10 three 5-minute slots per frame; only the surface (skin) value is stored
    SpO₂ 40 <day> bit 81 15 one-minute readings per frame, kept in 70–100
    BP, stress, sugar, HRV 55 <day> bit 83 three 15-minute slots per frame
    • End of a log: each one ends on its 23:45 slot, or when the stream goes quiet. A B9 reply means the ring has no log for that day.
    • Bit order: the vendor builds the bits least-significant first (utils.m.b).
    • The owner's ring (003A002AV138) sets bits 10, 81, 83 and 84. Its real 0x20 reply is in a test.
  • Temperature granted per unit. A ring that sets bit 10 is granted TEMPERATURE at runtime (JringCoordinator.bitmapGatedCapabilities). The family baseline still leaves it out, because SR08-class rings don't set that bit.

  • Calibration on the BP and glucose detail screens. A card shows the stored cuff or meter reference and a button to Settings → Calibration. The ring has no read-back: its 0x33 reply is only an acknowledgement.

  • Bug fix. TodayViewModel added the cuff reference to each BP reading, as if it were an offset. Nothing displayed those fields, so no wrong number was ever shown.

  • Docs.

    • docs/jring-56ff-plan.md:
      • the vendor-app findings;
      • the firmware lookup: V138 is current, on a Dialog chip, and the image is encrypted.
    • AGENTS.md: a summary.

Tests: JringSensorHistoryTest and new JringHistorySyncTest cases.

Audit: audits/2026-11-11-v2.16.2-calibration-sensor-history.md

Design canvas: not updated. The canvas tools weren't connected when this was written. The VitalDetail board still needs the Calibration card.

🤖 Generated with Claude Code

https://claude.ai/code/session_01P1t1aUqSUPd3whKXmgVm7w

…on on the detail screens

From the JRing 2.0.8 decompile: the app passes the ring's BP and sugar
through unchanged. The ring computes them from the profile (0x02) and
a cuff reference (0x33, write-only, default 120/80). The ring also
logs those estimates every 15 minutes (0x55, gated on 0x20 bit 83,
which the vendor builds LSB first). JringHistorySync now asks for it as
the third step per day, after heart rate, and ends a past day on its
23:45 slot. RingDecoder.decodeSensorHistory stores BP only when both
halves are set and every other value only when non-zero, as the vendor
does.

The BP and glucose detail screens gain a Calibration card: what the
estimate is calibrated against, and a button to Settings → Calibration.
TodayViewModel no longer adds the cuff reference to BP readings; it is
a reference the ring uses, not an offset.

Findings recorded in docs/jring-56ff-plan.md and AGENTS.md. Tests for
the decoder and the new pager step.

Claude-Session: https://claude.ai/code/session_01P1t1aUqSUPd3whKXmgVm7w
After each day's heart rate, the vendor asks for each offline log the ring
advertises, in this order: temperature (bit 10, 0x39), SpO₂ (bit 81, 0x40),
then the 0x55 sensor log. JringHistorySync now runs the same chain, ends a
leg on the 23:45 slot or when it settles, and skips a day the ring answers
with B9 ("getdayabyday failed").
- 0x40: 15 one-minute SpO₂ readings per frame, kept in the 70–100 band.
- 0x39: three 5-minute slots; only the surface (skin) value is stored.

The 0x20 reply now also reports TEMPERATURE when bit 10 is set, granted
per unit through JringCoordinator.bitmapGatedCapabilities. The owner's
ring (003A002AV138) sets bits 10, 81, 83 and 84. Tests use that ring's
real reply.

Claude-Session: https://claude.ai/code/session_01P1t1aUqSUPd3whKXmgVm7w
@gabrielbr gabrielbr changed the title Jring: 15-minute BP/stress/sugar/HRV history; calibration on the detail screens Jring: offline BP/stress/sugar/HRV, SpO₂ and temperature history; calibration on the detail screens Nov 11, 2026
@gabrielbr
gabrielbr merged commit 155546a into main Nov 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants