Skip to content

Commit 5dab230

Browse files
authored
LOOP-4098 Overlay basal from history timeline instead of schedule (#701)
* Overlay basal from history timeline instead of schedule * Remove file
1 parent b6f2594 commit 5dab230

File tree

5 files changed

+54
-67
lines changed

5 files changed

+54
-67
lines changed

Loop/Extensions/DoseStore+SimulatedCoreData.swift

+5-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extension DoseStore {
2121
private var simulatedLimit: Int { 10000 }
2222
private var suspendDuration: TimeInterval { .minutes(30) }
2323

24-
func generateSimulatedHistoricalPumpEvents(completion: @escaping (Error?) -> Void) {
24+
func generateSimulatedHistoricalPumpEvents() async throws {
2525
var startDate = Calendar.current.startOfDay(for: cacheStartDate)
2626
let endDate = Calendar.current.startOfDay(for: historicalEndDate)
2727
var index = 0
@@ -79,22 +79,19 @@ extension DoseStore {
7979

8080
// Process about a day's worth at a time
8181
if simulated.count >= 300 {
82-
if let error = addPumpEvents(events: simulated) {
83-
completion(error)
84-
return
85-
}
82+
try await addPumpEvents(events: simulated)
8683
simulated = []
8784
}
8885

8986
index += 1
9087
startDate = startDate.addingTimeInterval(simulatedBasalStartDateInterval)
9188
}
9289

93-
completion(addPumpEvents(events: simulated))
90+
try await addPumpEvents(events: simulated)
9491
}
9592

96-
func purgeHistoricalPumpEvents(completion: @escaping (Error?) -> Void) {
97-
purgePumpEventObjects(before: historicalEndDate, completion: completion)
93+
func purgeHistoricalPumpEvents() async throws {
94+
try await purgePumpEventObjects(before: historicalEndDate)
9895
}
9996
}
10097

Loop/Managers/DeviceDataManager.swift

+20-13
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,9 @@ final class DeviceDataManager {
308308
pumpManager = pumpManagerFromRawValue(pumpManagerRawValue)
309309
// Update lastPumpEventsReconciliation on DoseStore
310310
if let lastSync = pumpManager?.lastSync {
311-
doseStore.addPumpEvents([], lastReconciliation: lastSync) { _ in }
311+
Task {
312+
try? await doseStore.addPumpEvents([], lastReconciliation: lastSync)
313+
}
312314
}
313315
if let status = pumpManager?.status {
314316
updatePumpIsAllowingAutomation(status: status)
@@ -1047,16 +1049,15 @@ extension DeviceDataManager: PumpManagerDelegate {
10471049
dispatchPrecondition(condition: .onQueue(.main))
10481050
log.default("PumpManager:%{public}@ hasNewPumpEvents (lastReconciliation = %{public}@)", String(describing: type(of: pumpManager)), String(describing: lastReconciliation))
10491051

1050-
doseStore.addPumpEvents(events, lastReconciliation: lastReconciliation, replacePendingEvents: replacePendingEvents) { (error) in
1051-
if let error = error {
1052+
Task {
1053+
do {
1054+
try await doseStore.addPumpEvents(events, lastReconciliation: lastReconciliation, replacePendingEvents: replacePendingEvents)
1055+
} catch {
10521056
self.log.error("Failed to addPumpEvents to DoseStore: %{public}@", String(describing: error))
1057+
completion(error)
10531058
}
1054-
1055-
completion(error)
1056-
1057-
if error == nil {
1058-
NotificationCenter.default.post(name: .PumpEventsAdded, object: self, userInfo: nil)
1059-
}
1059+
completion(nil)
1060+
NotificationCenter.default.post(name: .PumpEventsAdded, object: self, userInfo: nil)
10601061
}
10611062
}
10621063

@@ -1131,6 +1132,10 @@ extension DeviceDataManager: CarbStoreDelegate {
11311132

11321133
// MARK: - DoseStoreDelegate
11331134
extension DeviceDataManager: DoseStoreDelegate {
1135+
func scheduledBasalHistory(from start: Date, to end: Date) async throws -> [AbsoluteScheduleValue<Double>] {
1136+
try await settingsManager.getBasalHistory(startDate: start, endDate: end)
1137+
}
1138+
11341139
func doseStoreHasUpdatedPumpEventData(_ doseStore: DoseStore) {
11351140
uploadEventListener.triggerUpload(for: .pumpEvent)
11361141
}
@@ -1175,10 +1180,12 @@ extension DeviceDataManager {
11751180

11761181
let devicePredicate = HKQuery.predicateForObjects(from: [testingPumpManager.testingDevice])
11771182
let insulinDeliveryStore = doseStore.insulinDeliveryStore
1178-
1179-
doseStore.resetPumpData { doseStoreError in
1180-
guard doseStoreError == nil else {
1181-
completion?(doseStoreError!)
1183+
1184+
Task {
1185+
do {
1186+
try await doseStore.resetPumpData()
1187+
} catch {
1188+
completion?(error)
11821189
return
11831190
}
11841191

Loop/Managers/LoopAppManager.swift

+16-31
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ class LoopAppManager: NSObject {
253253
cacheStore: cacheStore,
254254
cacheLength: localCacheDuration,
255255
longestEffectDuration: ExponentialInsulinModelPreset.rapidActingAdult.effectDuration,
256-
basalProfile: settingsManager.settings.basalRateSchedule,
257256
lastPumpEventsReconciliation: nil // PumpManager is nil at this point. Will update this via addPumpEvents below
258257
)
259258

@@ -499,21 +498,6 @@ class LoopAppManager: NSObject {
499498
}
500499
}
501500
.store(in: &cancellables)
502-
503-
// DoseStore still needs to keep updated basal schedule for now
504-
NotificationCenter.default.publisher(for: .LoopDataUpdated)
505-
.receive(on: DispatchQueue.main)
506-
.sink { [weak self] note in
507-
if let rawContext = note.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopUpdateContext.RawValue,
508-
let context = LoopUpdateContext(rawValue: rawContext),
509-
let self,
510-
context == .preferences
511-
{
512-
self.doseStore.basalProfile = self.settingsManager.settings.basalRateSchedule
513-
}
514-
}
515-
.store(in: &cancellables)
516-
517501
}
518502

519503
private func loopCycleDidComplete() async {
@@ -1016,15 +1000,16 @@ extension LoopAppManager: SimulatedData {
10161000
return
10171001
}
10181002
self.dosingDecisionStore.generateSimulatedHistoricalDosingDecisionObjects() { error in
1019-
guard error == nil else {
1020-
completion(error)
1021-
return
1022-
}
1023-
self.doseStore.generateSimulatedHistoricalPumpEvents() { error in
1003+
Task {
10241004
guard error == nil else {
10251005
completion(error)
10261006
return
10271007
}
1008+
do {
1009+
try await self.doseStore.generateSimulatedHistoricalPumpEvents()
1010+
} catch {
1011+
completion(error)
1012+
}
10281013
self.deviceDataManager.deviceLog.generateSimulatedHistoricalDeviceLogEntries() { error in
10291014
guard error == nil else {
10301015
completion(error)
@@ -1056,28 +1041,28 @@ extension LoopAppManager: SimulatedData {
10561041
return
10571042
}
10581043
Task { @MainActor in
1059-
self.doseStore.purgeHistoricalPumpEvents() { error in
1044+
do {
1045+
try await self.doseStore.purgeHistoricalPumpEvents()
1046+
} catch {
1047+
completion(error)
1048+
return
1049+
}
1050+
self.dosingDecisionStore.purgeHistoricalDosingDecisionObjects() { error in
10601051
guard error == nil else {
10611052
completion(error)
10621053
return
10631054
}
1064-
self.dosingDecisionStore.purgeHistoricalDosingDecisionObjects() { error in
1055+
self.carbStore.purgeHistoricalCarbObjects() { error in
10651056
guard error == nil else {
10661057
completion(error)
10671058
return
10681059
}
1069-
self.carbStore.purgeHistoricalCarbObjects() { error in
1060+
self.glucoseStore.purgeHistoricalGlucoseObjects() { error in
10701061
guard error == nil else {
10711062
completion(error)
10721063
return
10731064
}
1074-
self.glucoseStore.purgeHistoricalGlucoseObjects() { error in
1075-
guard error == nil else {
1076-
completion(error)
1077-
return
1078-
}
1079-
self.settingsManager.purgeHistoricalSettingsObjects(completion: completion)
1080-
}
1065+
self.settingsManager.purgeHistoricalSettingsObjects(completion: completion)
10811066
}
10821067
}
10831068
}

Loop/View Controllers/InsulinDeliveryTableViewController.swift

+10-12
Original file line numberDiff line numberDiff line change
@@ -362,37 +362,35 @@ public final class InsulinDeliveryTableViewController: UITableViewController {
362362
}
363363

364364
let sheet = UIAlertController(deleteAllConfirmationMessage: confirmMessage) {
365-
self.deleteAllObjects()
365+
Task {
366+
await self.deleteAllObjects()
367+
}
366368
}
367369
present(sheet, animated: true)
368370
}
369371

370372
private var deletionPending = false
371373

372-
private func deleteAllObjects() {
374+
private func deleteAllObjects() async {
373375
guard !deletionPending else {
374376
return
375377
}
376378

377379
deletionPending = true
378380

379-
let completion = { (_: DoseStore.DoseStoreError?) -> Void in
380-
DispatchQueue.main.async {
381-
self.deletionPending = false
382-
self.setEditing(false, animated: true)
383-
}
384-
}
385-
386381
let sinceDate = Date().addingTimeInterval(-InsulinDeliveryTableViewController.historicDataDisplayTimeInterval)
387382

388383
switch DataSourceSegment(rawValue: dataSourceSegmentedControl.selectedSegmentIndex)! {
389384
case .reservoir:
390-
doseStore?.deleteAllReservoirValues(completion)
385+
try? await doseStore?.deleteAllReservoirValues()
391386
case .history:
392-
doseStore?.deleteAllPumpEvents(completion)
387+
try? await doseStore?.deleteAllPumpEvents()
393388
case .manualEntryDose:
394-
doseStore?.deleteAllManuallyEnteredDoses(since: sinceDate, completion)
389+
try? await doseStore?.deleteAllManuallyEnteredDoses(since: sinceDate)
395390
}
391+
self.deletionPending = false
392+
self.setEditing(false, animated: true)
393+
396394
}
397395

398396
// MARK: - Table view data source

LoopTests/ViewModels/BolusEntryViewModelTests.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class BolusEntryViewModelTests: XCTestCase {
189189

190190
func testUpdatePredictedGlucoseValues() async throws {
191191
do {
192-
let input = try await delegate.fetchData(for: Self.exampleStartDate, disablingPreMeal: false)
192+
let input = try await delegate.fetchData(for: Self.exampleStartDate, disablingPreMeal: false, ensureDosingCoverageStart: nil)
193193
let prediction = try input.predictGlucose()
194194
await bolusEntryViewModel.update()
195195
XCTAssertEqual(prediction, bolusEntryViewModel.predictedGlucoseValues.map { PredictedGlucoseValue(startDate: $0.startDate, quantity: $0.quantity) })
@@ -200,7 +200,7 @@ class BolusEntryViewModelTests: XCTestCase {
200200

201201
func testUpdatePredictedGlucoseValuesWithManual() async throws {
202202
do {
203-
let input = try await delegate.fetchData(for: Self.exampleStartDate, disablingPreMeal: false)
203+
let input = try await delegate.fetchData(for: Self.exampleStartDate, disablingPreMeal: false, ensureDosingCoverageStart: nil)
204204
let prediction = try input.predictGlucose()
205205
await bolusEntryViewModel.update()
206206
bolusEntryViewModel.manualGlucoseQuantity = Self.exampleManualGlucoseQuantity
@@ -870,7 +870,7 @@ fileprivate class MockBolusEntryViewModelDelegate: BolusEntryViewModelDelegate {
870870
automaticBolusApplicationFactor: 0.4
871871
)
872872

873-
func fetchData(for baseTime: Date, disablingPreMeal: Bool) async throws -> StoredDataAlgorithmInput {
873+
func fetchData(for baseTime: Date, disablingPreMeal: Bool, ensureDosingCoverageStart: Date?) async throws -> StoredDataAlgorithmInput {
874874
loopStateInput.predictionStart = baseTime
875875
return loopStateInput
876876
}

0 commit comments

Comments
 (0)