Skip to content

Send each dose with a dose id and keep its metadata in Loop - #2675

Merged
ps2 merged 1 commit into
next-devfrom
dose-id
Nov 12, 2026
Merged

ps2 merged 1 commit into
next-devfrom
dose-id

Conversation

@ps2

@ps2 ps2 commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

Adopts LoopKit/LoopKit#695: pump managers now get an opaque doseId instead of decisionId, and Loop keeps the dose's metadata itself.

DeviceDataManager creates a dose id for each bolus and temp basal, stores a DoseMetadata record for it in DoseMetadataStore, then sends the command. Because the record is written first, a dose reported after a relaunch still finds its metadata. If storing fails, the failure is logged and the dose still goes out.

Path origin device decision
Automatic dosing automatic phone the loop's dosing decision. A temp basal and a bolus from one cycle each get their own id.
Bolus screen, simple bolus user phone their dosing decision
Watch bolus user watch its dosing decision
Retry from a bolus failure notification user phone the original decision
Remote command remote what the service passes

The bolus activation type is recorded as well.

  • The bolus and simple-bolus delegates (enactBolus(units:metadata:activationType:)) take metadata instead of a decision id. DeliveryDelegate.enact(bolus:tempBasal:decisionId:) is unchanged for automatic dosing.
  • The insulin delivery log and the status screen's dose detail find a dose's dosing decision through DoseMetadataStore.decisionIds(for:). Doses recorded before this change keep their decision id as their dose id, so they still resolve.

Tests

  • DoseEnactorTests.testEachDoseGetsItsOwnDoseId
  • DeviceDataManagerTests.testEnactBolusStoresMetadataForTheDoseIdSentToThePump
  • DeviceDataManagerTests.testAutomaticDosesStoreMetadataWithTheDecision
  • BolusEntryViewModelTests checks the metadata it sends.
  • The full LoopWorkspace test run passes on an iPhone 17 simulator, including Loop's 433 tests.

Needs LoopKit/LoopKit#695, plus the pump manager PRs for the workspace to build.

Adopts LoopKit's doseId: DeviceDataManager gives every bolus and temp basal its own dose id and stores a DoseMetadata record for it before sending the command, so a dose reported after a relaunch still finds its metadata. A failure to store the metadata is logged and does not stop the dose.

- Automatic dosing: origin automatic, phone, the loop's dosing decision. A temp basal and a bolus from one cycle now get separate ids for the same decision.
- Bolus screen and simple bolus: origin user, phone, their dosing decision.
- Watch: origin user, watch.
- Retry from a bolus failure notification: origin user, phone, the original decision.
- Remote commands: origin remote.

The bolus activation type is recorded too. The bolus and simple-bolus delegates take the metadata in place of a decision id. The insulin delivery log and the dose detail on the status screen find a dose's dosing decision through the metadata store; doses recorded before this change keep their decision id as their dose id.
@ps2
ps2 merged commit 1b9357c into next-dev Nov 12, 2026
ps2 added a commit to LoopKit/LoopWorkspace that referenced this pull request Nov 12, 2026
…#586)

Async CGM/pump manager delegate calls without delegateQueue (LoopKit/LoopKit#696, LoopKit/Loop#2677 and the plugin PRs), doses identified by a Loop-owned doseId (LoopKit/LoopKit#695, LoopKit/Loop#2675), and dose metadata carried on DoseEntry (LoopKit/LoopKit#699, LoopKit/Loop#2683).

Submodules: CGMBLEKit, EversenseKit, G7SensorKit, LibreLoop, LibreTransmitter, Loop, LoopKit, MedtrumKit, MinimedKit, NightscoutRemoteCGM, OmnipodKit, TidepoolService, dexcom-share-client-swift.
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