Remote Bolus Dev#1508
Conversation
5b2e804 to
9efa688
Compare
2a07601 to
c8d6c9a
Compare
ps2
left a comment
There was a problem hiding this comment.
Thanks Bill, could you address the comments? Otherwise, this is looking great! Thanks!
|
|
||
| loopAppManager.initialize(windowProvider: self, launchOptions: launchOptions) | ||
| loopAppManager.launch() | ||
| UIApplication.shared.registerForRemoteNotifications() |
There was a problem hiding this comment.
This is already happening in NotificationManager; we should probably only do this once.
There was a problem hiding this comment.
@ps2 This is part of the proposed fix outlined in 1536 (among others). From what I can tell, we only fetch the token via registerForRemoteNotifications during onboarding. Since we can't persist the token per iOS guidelines, it will be available in-memory only and not be available for later upload after an app reboot. Here's the cases where that could pose an issue:
- User chooses to setup Nightscout after onboarding.
- User goes offline during onboarding process.
I think attempting to fetch it on each startup would be good protection against the above scenarios -- it will always be available to in memory and uploaded to Nightscout when needed.
If that seems reasonable, I agree we don't need it in both places. How about I remove it from onboarding? Or are there other considerations I'm not thinking of?
There was a problem hiding this comment.
I updated this PR in this way. Please let me know if any any questions on that.
| case .cancelTemporaryOverride: | ||
| log.default("Canceling temporary override from remote command") | ||
| loopManager.settings.scheduleOverride = nil | ||
| case .bolusEntry(let bolusValue): |
There was a problem hiding this comment.
We should trigger a user notification when this happens. Or is the push notification including foreground text?
There was a problem hiding this comment.
I've added notifications to indicate success and failure once the remote notification is processed. That should handle the foreground notification and allow for better troubleshooting for both foreground and background states. I've added screenshots and more discussion in Zulip https://loop.zulipchat.com/#narrow/stream/144182-development/topic/Remote.20bolus.20.2F.20remote.20carbs
| log.default("No max bolus detected. Aborting...") | ||
| } | ||
| case .carbsEntry(let newEntry): | ||
| log.default("Adding carbs entry.") |
There was a problem hiding this comment.
A local notification should happen with this too.
| @@ -375,6 +375,8 @@ | |||
| 89FE21AD24AC57E30033F501 /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89FE21AC24AC57E30033F501 /* Collection.swift */; }; | |||
| A90EF53C25DEF06200F32D61 /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16DA84122E8E112008624C2 /* PluginManager.swift */; }; | |||
| A90EF54425DEF0A000F32D61 /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4374B5EE209D84BE00D17AA8 /* OSLog.swift */; }; | |||
There was a problem hiding this comment.
Base32 and OneTimePassword are the new git submodules that are linked in the workspace. I believe they need added to the Loop project, and to be embedded, in order for things to work.
| loopManager.settings.scheduleOverride = nil | ||
| case .bolusEntry(let bolusAmount): | ||
| log.default("Enacting remote bolus entry: %{public}@", String(describing: bolusAmount)) | ||
|
|
There was a problem hiding this comment.
Add explicit guards for the various error conditions on a remote bolus. In there is an error, that will be reported back as a user local notification.
| log.default("Remote bolus higher than maximum. Aborting...") | ||
| return | ||
| } | ||
|
|
There was a problem hiding this comment.
When enacting the bolus here, we may get a specialized error from the enactBolus API which will also be presented in a local notification.... otherwise we show a local notification with a success message.
| } else { | ||
| NotificationManager.sendRemoteBolusNotification(amount: bolusAmount) | ||
| } | ||
| } |
There was a problem hiding this comment.
Same paradigm here for remote carb entries.
| log.default("Invalid carb entry amount. Aborting...") | ||
| return | ||
| } | ||
|
|
There was a problem hiding this comment.
Added this check that we don't exceed the max carb entry amount.
| log.default("Carbs higher than maximum. Aborting...") | ||
| return | ||
| } | ||
|
|
There was a problem hiding this comment.
Finally we attempt to add the carbs, and also show an error if that fails (unlikely - would be Core Data issue it seems)
| } | ||
|
|
||
| // MARK: - Remote Notification | ||
|
|
There was a problem hiding this comment.
Pete - Since you looked over this before I realized I should have this feature flag check. At least that is what is done in dev now.
| @@ -324,10 +332,13 @@ extension LoopAppManager: UNUserNotificationCenterDelegate { | |||
| case LoopNotificationCategory.bolusFailure.rawValue, | |||
| LoopNotificationCategory.pumpBatteryLow.rawValue, | |||
| LoopNotificationCategory.pumpExpired.rawValue, | |||
There was a problem hiding this comment.
New notifications for remote bolus/carbs. More on that below.
| @@ -798,7 +798,7 @@ extension LoopDataManager { | |||
| maximumBasalRatePerHour: loopSettings.maximumBasalRatePerHour, | |||
| maximumBolus: loopSettings.maximumBolus, | |||
| suspendThreshold: loopSettings.suspendThreshold, | |||
There was a problem hiding this comment.
This was discussed in #1536... But basically loopSettings doeesn't store the deviceToken so this will be nil. We may want to just remove that property altogether to avoid the confusion but I'd need to verify that is ok.
| @@ -67,14 +67,6 @@ extension NotificationManager { | |||
| center.requestAuthorization(options: authOptions) { (granted, error) in | |||
| UNUserNotificationCenter.current().getNotificationSettings { settings in | |||
| completion(settings.authorizationStatus) | |||
There was a problem hiding this comment.
Discussed in #1536 but need to make sure this is called on each startup since we are not persisting it anywhere. Moved to LoopAppManager above.
| @@ -156,6 +148,85 @@ extension NotificationManager { | |||
| UNUserNotificationCenter.current().add(request) | |||
| } | |||
| } | |||
There was a problem hiding this comment.
Helpers to send the new local notifications.
| @@ -361,6 +361,21 @@ extension RemoteDataServicesManager { | |||
|
|
|||
| } | |||
|
|
|||
There was a problem hiding this comment.
Check our data services for one to validate our notification here. As a future enhancement, data services like Nightscout could provide some kind of identifier in the push payload that maps to the service. That would allow Loop to dispatch the notification to the corresponding service rather than sending it to all the services like this.
| import Foundation | ||
| import LoopKit | ||
| import HealthKit | ||
|
|
There was a problem hiding this comment.
I don't believe this was being used from what I can tell. But it looks like the right structure to add new remote command errors like I needed for remote bolus/carbs.
| case exceedsMaxBolus | ||
| case exceedsMaxCarbs | ||
| case invalidCarbs | ||
|
|
There was a problem hiding this comment.
I'm using this description in the local notifications that show.
| self = .cancelTemporaryOverride | ||
| } else if let bolusValue = notification["bolus-entry"] as? Double { | ||
| self = .bolusEntry(bolusValue) | ||
| } else if let carbsValue = notification["carbs-entry"] as? Double { |
There was a problem hiding this comment.
Jose had this original comment on the default absorption value. I hadn't dug in but it doesn't seem critical now either.
|
Token management has been resolved in dev, I believe. This PR needs to be updated to resolve conflicts with the latest dev. I'll see if I can land the NightScoutService soon. |
|
@ps2 conflicts + token workarounds have been removed. |
|
Merged these changes in 5b25c83. Forgot to squash, so they're all separate in the log. :-/ |
This PR includes changes to the Loop module to support remote/bolus in dev. See the workspace PR for more details on the overall effort. Comments added inline for review.