Show glucose predictions and allow bolus recommendations without pod#2446
Open
Chris-Almond wants to merge 1 commit into
Open
Show glucose predictions and allow bolus recommendations without pod#2446Chris-Almond wants to merge 1 commit into
Chris-Almond wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Show predicted glucose and bolus recommendation when no active delivery device is paired
Closes #2445
Overview
When no active pod is paired, for example during a pod change or after a pod fault, Loop suppresses both the predicted glucose curve and the bolus recommendation entirely. This happens because the pump data recency check throws an error when no pod is active, since
doseStore.lastAddedPumpDatareturns.distantPast, which always exceedsinputDataRecencyInterval.This PR decouples the visualization and bolus recommendation paths from the pump recency check when no active delivery device is detected, while preserving the original conservative behavior when a pod is paired but temporarily out of communication.
Approach
A new computed property
shouldModelAsNoDeliveryis added as an extension onPumpManagerStatusin LoopKit. This property returnstruewhenbasalDeliveryState == .active(.distantPast), which is the sentinel value used by bothOmniBLEPumpManagerandOmnipodPumpManagerto indicate no active pod is paired. I chose this approach to keep the detection logic in one place, close to the data it depends on, and avoid scattering pump-specific logic across the codebase. This was the least disruptive way I found to introduce this change.For pump types that do not use this sentinel (
.active(.distantPast)) (e.g. Medtronic/RileyLink),shouldModelAsNoDeliverywill never returntrueas long as those pumps have apumpManagerwith anypumpStatus. When no pump manager is present at all, the property defaults totruewhich treats the state of an unconfigured pump as no delivery.Changes
PumpManagerStatusextensionshouldModelAsNoDelivery: Boolcomputed property based onbasalDeliveryStatePrediction curve
requireRecentPumpDataparameter (defaulttrue) topredictGlucoseinLoopDataManager, preserving existing behavior for all other call sites. (Not sure if this was necessary but it felt safest).shouldModelAsNoDeliveryistrue, the suspension of insulin delivery effect is automatically included in the prediction, since no basal is being deliveredupdatePredictedGlucoseAndRecommendedDosereturns early before computing a dose recommendation when pump data is staleBolus recommendation
shouldModelAsNoDeliveryistrue, the full prediction-based bolus recommendation algorithm runs using the suspension-adjusted prediction curve, bypassing the pump recency checknoPumpConnectednotice is surfaced on the bolus screen, distinct fromstalePumpData, to clearly communicate the context to the userPredicted Glucose chart
shouldModelAsNoDeliveryistrue, the Suspension of Insulin Delivery row in the prediction modification selection picker is shown as active, grayed out, non-interactive, and checked, since it reflects reality rather than a hypotheticalWarning text
stalePumpDatawarning caption to no longer claim a recommendation cannot be madenoPumpConnectedwarning case distinct fromstalePumpDataAffected files
Loop/Managers/LoopDataManager.swiftLoop/View Models/BolusEntryViewModel.swiftLoop/View Models/ManualEntryDoseViewModel.swiftLoop/View Controllers/PredictionTableViewController.swiftLoop/Views/BolusEntryView.swiftLoop/Extensions/DeviceDataManager+BolusEntryViewModelDelegate.swiftLoopTests/ViewModels/BolusEntryViewModelTests.swiftTesting
RFC / Acknowledgements
Detection mechanism
As mentioned above, the
shouldModelAsNoDeliveryproperty relies on the.active(.distantPast)sentinel value used byOmniBLEPumpManagerandOmnipodPumpManagerto signal no active pod. This is an implementation detail rather than a formally documented contract, and could theoretically change without warning. It is also specific to pod-based pump managers. Tube pumps that do not use this sentinel should be unaffected by this change.A cleaner long-term solution would be to add
shouldModelAsNoDeliverydirectly to thePumpManagerprotocol in LoopKit with a default implementation offalse, allowing each pump manager to explicitly opt in based on its own internal state. This was considered but deferred to keep the scope of this PR contained to the Loop repo. Feedback on whether that approach is preferred is requested and more than welcome.Default behavior when no pump manager is present
When
pumpManagerStatusisnil(no pump configured at all),shouldModelAsNoDeliverydefaults totrue. This means the feature also activates in the fully unconfigured state, which I felt to be a more useful default, though I honestly can't envision users commonly using Loop without a configured pump/pumpManager. Therefore a user with no pump configured still benefits from seeing a prediction. If the reviewers preferfalsein this case, I'm open to that, as it is a one-line modification to adjust the behavior on what I think is an edge-case, but please let me know!Non-Omnipod pump testing
This change has only been tested live with Omnipod Dash. Contributions from users of other pump types, particularly those that might use or be aware of other causes of
.active(.distantPast)in unexpected ways, are welcome, as the codebase only has 2 (now 3) references to that combination.Screenshots
Note: some of the below screenshots include 2 visual-only modifications to the prediction line color (signaling above/below ranges) and a thin red vertical bar that shows the current time across all charts. Those changes are from some of my very old personal features and they are not included in this PR.
dashboardActualStandardWithPodState






dashboardNoInsulinActual
(disregard hidden video marker)
dashboardNoPodActual_predictionsReflectingUpdates
dashboardNoPodActual
dashboardPredictionLineSimulatorNoPumpConfigured
predictionsActual