Skip to content

Defer forgetting sensor on suspected session end to avoid long reconnection outages - #62

Open
cheets wants to merge 1 commit into
LoopKit:mainfrom
cheets:fix/g7-suspected-session-end-grace
Open

Defer forgetting sensor on suspected session end to avoid long reconnection outages#62
cheets wants to merge 1 commit into
LoopKit:mainfrom
cheets:fix/g7-suspected-session-end-grace

Conversation

@cheets

@cheets cheets commented Aug 19, 2026

Copy link
Copy Markdown

Problem

When a G7 disconnects before authentication completes, G7Sensor reports suspectedEndOfSession=true and G7CGMManager immediately forgets the sensor (sensorID = nil, peripheral forgotten) and starts scanning for a new one.

The same disconnect signature is produced by ordinary transient BLE handshake failures — auth notification enable timeouts, unknownCharacteristic during incomplete service discovery, CBError encryption failures. In a week of device logs I collected, 118 suspected session ends fired, of which exactly 1 was a real session end. Each false positive forgets the tracked peripheral, which downgrades reconnection from an OS-level pending connect (instant wake when the sensor next transmits) to a throttled background scan plus full re-discovery. Result: recurring 10–40 minute glucose outages ("Searching for sensor"), during which Loop cannot dose. Worst observed: 45 minutes.

Change

On a suspected session end, keep tracking the current sensor and defer scanForNewSensor() by a 15-minute wall-clock grace period:

  • Any received glucose or backfill message cancels the pending scan — the session is proven alive.
  • If nothing is heard for the full grace period, the sensor is forgotten and scanning starts, preserving automatic switch to a new sensor.
  • Immediate switching on sensorFailed / sessionEnded algorithm states is unchanged — a sensor that announces its own session end still triggers an instant scan.
  • A manual "scan for new sensor" cancels any pending deferred scan.

The grace period uses a wall-clock deadline so device sleep cannot postpone detection of a genuinely ended session.

Also adds unit tests for the new behavior, with small DI seams to make G7CGMManager testable (central-manager factory to avoid the state-restoration exception in test bundles, injectable G7BluetoothManager, internal manager init), and a shared scheme with a test action.

Field results

I have been running this for a month on my own Loop with no issues. From exported device logs:

before after (week 1) after (week 5)
suspected session ends 15.2/day 19.6/day 7.2/day
sensor forgets 15.2/day 0.4/day 0
grace periods cancelled by resumed comms 129/132 45/45
glucose gaps ≥ 12 min ~125 min/day 54 min/day

A real sensor swap during the trial was handled by the unchanged sessionEnded message path: old sensor forgotten immediately, new sensor discovered 3 minutes after activation, during warmup.

Notes

This overlaps in intent with the scanning-fix branch ("Continue with sensor even after auth without control msg", "Use remote disconnect without auth/data as end-of-session detection again") — same underlying observation that auth-less remote disconnects are unreliable as a session-end signal. This change keeps the existing detection but makes acting on it tolerant to transient failures. Happy to adapt if maintainers prefer the scanning-fix direction.

A remote disconnect before authentication completes is treated as a
session end, immediately forgetting the sensor and scanning from
scratch. The same disconnect signature occurs on transient BLE
handshake failures (auth notification timeouts, encryption failures),
where forgetting the tracked peripheral downgrades reconnection from
an OS-level pending connect to a throttled background scan, causing
10-40 minute glucose outages. Field logs showed 118 suspected session
ends in 7 days of which 1 was a real session end.

Keep tracking the sensor on a suspected session end and defer the
scan-for-new-sensor by a 15 minute wall-clock grace period, cancelled
when any glucose or backfill message arrives. A real session end still
switches sensors: the stopped sensor stays silent, the grace period
expires, and the new sensor is discovered during its warmup. Immediate
switch on sensorFailed/sessionEnded algorithm states is unchanged.

Also add DI seams (central manager factory, injectable bluetooth
manager, internal manager init) so G7CGMManager is unit-testable, plus
a shared scheme with a test action.
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