Skip to content

fix(luckring): omit HRV for the TK18 family (#112) - #122

Merged
foureight84 merged 2 commits into
mainfrom
fix/112-luckring-hide-hrv
Oct 15, 2026
Merged

foureight84 merged 2 commits into
mainfrom
fix/112-luckring-hide-hrv

Conversation

@foureight84

Copy link
Copy Markdown
Owner

Follow-up to #112. The LuckRing family (the TK18 is its only model) no longer reads, stores or shows HRV.

Why

  • The byte doesn't behave like HRV. The ring sends one HRV byte per reading (types 45 live and 42 history), and we decode it the same way the vendor SDK's K6_HeartStruct does. But nothing shows it is HRV in milliseconds:
  • The vendor app doesn't show it either. LuckRing 1.6.3 stores the byte and never displays it. Every HRV screen there shows AppUtils.getRomHrv(), a random number from the user's age band.

Changes

  • LuckRingCoordinator: drops HRV and MANUAL_HRV, so the HRV card and everything keyed on that capability stay hidden. The doc comment records why. Capabilities are re-stamped on every connect (RingBLEClient DeviceIdentified), so existing TK18 users get the change on their next connection with no migration.
  • LuckRingHistorySync: no longer requests history type 42. That also makes each sync one step shorter.
  • LuckRingDriver: drops any HRV event the ring pushes on its own. The frame is still ACKed and still appears in the raw-packet feed. The decoder is unchanged, so turning HRV back on later is a small change if someone works out what the byte means.
  • docs/ios-sync.md: records this as a deliberate divergence. iOS still declares .hrv, .manualHrv, so it's an upstream candidate.

Not changed

  • HRV already stored is kept, not deleted. It is hidden on screen through the capability gate. LuckRing reports its own stress, so derived stress (which reads stored HRV directly) doesn't apply to it.
  • Stress (types 52/53) still shows. It's the ring's own stress value, not derived from the HRV byte.

Tests

./gradlew :app:testDebugUnitTest: all tests pass. New LuckRingDriverTest cases cover two things: HRV frames on both data types are ACKed but produce no HRV events, and the coordinator declares no HRV capability. The LuckRingHistorySyncTest catalog check is updated.

Not checked on a device.

🤖 Generated with Claude Code

The ring sends one HRV byte per reading (types 45 live / 42 history), decoded exactly as the vendor
SDK's K6_HeartStruct does, but nothing shows it is HRV in milliseconds: the TK18 in #112 sent
107-168 in one evening, masking the top bit didn't help, and no packet carries beat intervals to
compute HRV from. The official LuckRing app (1.6.3) stores the byte and never shows it; every HRV
screen displays AppUtils.getRomHrv(), a random value from the user's age band.

- LuckRingCoordinator no longer declares HRV / MANUAL_HRV, so the HRV card and everything keyed on
  the capability stay hidden. Capabilities are re-stamped on every connect, so existing TK18 users
  pick this up on their next connection.
- The history pass no longer requests type 42.
- LuckRingDriver drops any HRV event the ring pushes on its own; the frame is still ACKed and still
  shows in the raw-packet feed.

HRV rows already stored are kept, not deleted.
@foureight84
foureight84 merged commit fc69ac9 into main Oct 15, 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.

1 participant