Explorar el Código

determination Storage, refactoring

polscm32 hace 1 año
padre
commit
ba0086eefa

+ 4 - 0
FreeAPS.xcodeproj/project.pbxproj

@@ -283,6 +283,7 @@
 		583684082BD195A700070A60 /* Determination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583684072BD195A700070A60 /* Determination.swift */; };
 		5837A5302BD2E3C700A5DC04 /* CarbEntryStored+helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5837A52F2BD2E3C700A5DC04 /* CarbEntryStored+helper.swift */; };
 		585E2CAE2BE7BF46006ECF1A /* PumpEvent+helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585E2CAD2BE7BF46006ECF1A /* PumpEvent+helper.swift */; };
+		5864E8592C42CFAE00294306 /* DeterminationStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5864E8582C42CFAE00294306 /* DeterminationStorage.swift */; };
 		587DA1F62B77F3DD00B28F8A /* SettingsRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */; };
 		5887527C2BD986E1008B081D /* OpenAPSBattery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5887527B2BD986E1008B081D /* OpenAPSBattery.swift */; };
 		588752842BD9986A008B081D /* OpenAPS_Battery+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588752822BD9986A008B081D /* OpenAPS_Battery+CoreDataClass.swift */; };
@@ -895,6 +896,7 @@
 		583684072BD195A700070A60 /* Determination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Determination.swift; sourceTree = "<group>"; };
 		5837A52F2BD2E3C700A5DC04 /* CarbEntryStored+helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarbEntryStored+helper.swift"; sourceTree = "<group>"; };
 		585E2CAD2BE7BF46006ECF1A /* PumpEvent+helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpEvent+helper.swift"; sourceTree = "<group>"; };
+		5864E8582C42CFAE00294306 /* DeterminationStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeterminationStorage.swift; sourceTree = "<group>"; };
 		587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRowView.swift; sourceTree = "<group>"; };
 		5887527B2BD986E1008B081D /* OpenAPSBattery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenAPSBattery.swift; sourceTree = "<group>"; };
 		588752822BD9986A008B081D /* OpenAPS_Battery+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenAPS_Battery+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
@@ -1879,6 +1881,7 @@
 				38F3B2EE25ED8E2A005C48AA /* TempTargetsStorage.swift */,
 				CE82E02428E867BA00473A9C /* AlertStorage.swift */,
 				BDC2EA442C3043B000E5BBD0 /* OverrideStorage.swift */,
+				5864E8582C42CFAE00294306 /* DeterminationStorage.swift */,
 			);
 			path = Storage;
 			sourceTree = "<group>";
@@ -3138,6 +3141,7 @@
 				1BBB001DAD60F3B8CEA4B1C7 /* ISFEditorStateModel.swift in Sources */,
 				F816826028DB441800054060 /* BluetoothTransmitter.swift in Sources */,
 				DD68889D2C386E17006E3C44 /* NightscoutExercise.swift in Sources */,
+				5864E8592C42CFAE00294306 /* DeterminationStorage.swift in Sources */,
 				BD7DA9A72AE06E2B00601B20 /* BolusCalculatorConfigProvider.swift in Sources */,
 				38192E0D261BAF980094D973 /* ConvenienceExtensions.swift in Sources */,
 				FEFA5C0F299F810B00765C17 /* Core_Data.xcdatamodeld in Sources */,

+ 28 - 26
FreeAPS/Sources/APS/APSManager.swift

@@ -67,6 +67,7 @@ final class BaseAPSManager: APSManager, Injectable {
     @Injected() private var tempTargetsStorage: TempTargetsStorage!
     @Injected() private var carbsStorage: CarbsStorage!
     @Injected() private var announcementsStorage: AnnouncementsStorage!
+    @Injected() private var determinationStorage: DeterminationStorage!
     @Injected() private var deviceDataManager: DeviceDataManager!
     @Injected() private var nightscout: NightscoutManager!
     @Injected() private var settingsManager: SettingsManager!
@@ -245,7 +246,10 @@ final class BaseAPSManager: APSManager, Injectable {
 
                 // Open loop completed
                 guard settings.closedLoop else {
-                    nightscout.uploadStatus()
+                    Task.detached(priority: .low) {
+                        await self.nightscout.uploadStatus()
+                    }
+
                     loopStatRecord.end = Date()
                     loopStatRecord.duration = roundDouble((loopStatRecord.end! - loopStatRecord.start).timeInterval / 60, 2)
                     loopStatRecord.loopStatus = "Success"
@@ -253,7 +257,9 @@ final class BaseAPSManager: APSManager, Injectable {
                     return
                 }
 
-                nightscout.uploadStatus()
+                Task.detached(priority: .low) {
+                    await self.nightscout.uploadStatus()
+                }
 
                 // Closed loop - enact Determination
                 try await enactDetermination()
@@ -270,9 +276,7 @@ final class BaseAPSManager: APSManager, Injectable {
 
             // End background task after all the operations are completed
             if let backgroundTask = self.backGroundTaskID {
-                Task {
-                    await UIApplication.shared.endBackgroundTask(backgroundTask)
-                }
+                await UIApplication.shared.endBackgroundTask(backgroundTask)
                 self.backGroundTaskID = .invalid
             }
         }
@@ -298,7 +302,7 @@ final class BaseAPSManager: APSManager, Injectable {
         loopStats(loopStatRecord: loopStatRecord)
 
         if settings.closedLoop {
-            await reportEnacted(received: error == nil)
+            await reportEnacted(wasEnacted: error == nil)
         }
 
         // End of the BG tasks
@@ -577,7 +581,9 @@ final class BaseAPSManager: APSManager, Injectable {
                     } else {
                         debug(.apsManager, "Pump suspended by Announcement")
                         self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                        self.nightscout.uploadStatus()
+                        Task {
+                            await self.nightscout.uploadStatus()
+                        }
                     }
                 }
             case .resume:
@@ -590,8 +596,9 @@ final class BaseAPSManager: APSManager, Injectable {
                     } else {
                         debug(.apsManager, "Pump resumed by Announcement")
                         self.announcementsStorage.storeAnnouncements([announcement], enacted: true)
-                        self.nightscout.uploadStatus()
-                    }
+                        Task {
+                            await self.nightscout.uploadStatus()
+                        } }
                 }
             }
         case let .looping(closedLoop):
@@ -661,19 +668,10 @@ final class BaseAPSManager: APSManager, Injectable {
         }
     }
 
-    private func fetchDetermination() async -> NSManagedObjectID? {
-        await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: OrefDetermination.self,
-            onContext: privateContext,
-            predicate: NSPredicate.predicateFor30MinAgoForDetermination,
-            key: "deliverAt",
-            ascending: false,
-            fetchLimit: 1
-        ).first?.objectID
-    }
-
     private func enactDetermination() async throws {
-        guard let determinationID = await fetchDetermination() else {
+        guard let determinationID = await determinationStorage
+            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination).first
+        else {
             throw APSError.apsError(message: "Determination not found")
         }
 
@@ -725,14 +723,16 @@ final class BaseAPSManager: APSManager, Injectable {
         bolusProgress.send(0)
     }
 
-    private func reportEnacted(received: Bool) async {
-        guard let determinationID = await fetchDetermination() else {
+    private func reportEnacted(wasEnacted: Bool) async {
+        guard let determinationID = await determinationStorage
+            .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination).first
+        else {
             return
         }
         await privateContext.perform {
             if let determinationUpdated = self.privateContext.object(with: determinationID) as? OrefDetermination {
                 determinationUpdated.timestamp = Date()
-                determinationUpdated.received = received
+                determinationUpdated.enacted = wasEnacted
 
                 do {
                     guard self.privateContext.hasChanges else { return }
@@ -744,9 +744,11 @@ final class BaseAPSManager: APSManager, Injectable {
                     )
                 }
 
-                debug(.apsManager, "Determination enacted. Received: \(received)")
+                debug(.apsManager, "Determination enacted. Enacted: \(wasEnacted)")
 
-                self.nightscout.uploadStatus()
+                Task.detached(priority: .low) {
+                    await self.nightscout.uploadStatus()
+                }
 
                 Task.detached(priority: .low) {
                     await self.statistics()

+ 66 - 0
FreeAPS/Sources/APS/Storage/DeterminationStorage.swift

@@ -0,0 +1,66 @@
+import CoreData
+import Foundation
+import Swinject
+
+protocol DeterminationStorage {
+    func fetchLastDeterminationObjectID(predicate: NSPredicate) async -> [NSManagedObjectID]
+    func getForecasts(for determinationID: NSManagedObjectID, in context: NSManagedObjectContext) -> [Forecast]
+    func getForecastValues(for forecastID: NSManagedObjectID, in context: NSManagedObjectContext) -> [ForecastValue]
+}
+
+final class BaseDeterminationStorage: DeterminationStorage, Injectable {
+    private let viewContext = CoreDataStack.shared.persistentContainer.viewContext
+    private let backgroundContext = CoreDataStack.shared.newTaskContext()
+
+    init(resolver: Resolver) {
+        injectServices(resolver)
+    }
+
+    func fetchLastDeterminationObjectID(predicate: NSPredicate) async -> [NSManagedObjectID] {
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
+            ofType: OrefDetermination.self,
+            onContext: backgroundContext,
+            predicate: predicate,
+            key: "deliverAt",
+            ascending: false,
+            fetchLimit: 1
+        )
+        return await backgroundContext.perform {
+            results.map(\.objectID)
+        }
+    }
+
+    func getForecasts(for determinationID: NSManagedObjectID, in context: NSManagedObjectContext) -> [Forecast] {
+        do {
+            guard let determination = try context.existingObject(with: determinationID) as? OrefDetermination,
+                  let forecastSet = determination.forecasts,
+                  let forecasts = Array(forecastSet) as? [Forecast]
+            else {
+                return []
+            }
+            return forecasts
+        } catch {
+            debugPrint(
+                "Failed \(DebuggingIdentifiers.failed) to fetch OrefDetermination with ID \(determinationID): \(error.localizedDescription)"
+            )
+            return []
+        }
+    }
+
+    func getForecastValues(for forecastID: NSManagedObjectID, in context: NSManagedObjectContext) -> [ForecastValue] {
+        do {
+            guard let forecast = try context.existingObject(with: forecastID) as? Forecast,
+                  let forecastValueSet = forecast.forecastValues,
+                  let forecastValues = Array(forecastValueSet) as? [ForecastValue]
+            else {
+                return []
+            }
+            return forecastValues.sorted(by: { $0.index < $1.index })
+        } catch {
+            debugPrint(
+                "Failed \(DebuggingIdentifiers.failed) to fetch Forecast with ID \(forecastID): \(error.localizedDescription)"
+            )
+            return []
+        }
+    }
+}

+ 1 - 0
FreeAPS/Sources/Assemblies/StorageAssembly.swift

@@ -9,6 +9,7 @@ final class StorageAssembly: Assembly {
         container.register(FileStorage.self) { _ in BaseFileStorage() }
         container.register(PumpHistoryStorage.self) { r in BasePumpHistoryStorage(resolver: r) }
         container.register(OverrideStorage.self) { r in BaseOverrideStorage(resolver: r) }
+        container.register(DeterminationStorage.self) { r in BaseDeterminationStorage(resolver: r) }
         container.register(GlucoseStorage.self) { r in BaseGlucoseStorage(resolver: r) }
         container.register(TempTargetsStorage.self) { r in BaseTempTargetsStorage(resolver: r) }
         container.register(CarbsStorage.self) { r in BaseCarbsStorage(resolver: r) }

+ 2 - 16
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -15,6 +15,7 @@ extension Bolus {
         @Injected() var nsManager: NightscoutManager!
         @Injected() var carbsStorage: CarbsStorage!
         @Injected() var glucoseStorage: GlucoseStorage!
+        @Injected() var determinationStorage: DeterminationStorage!
 
         @Published var predictions: Predictions?
         @Published var amount: Decimal = 0
@@ -619,26 +620,11 @@ extension Bolus.StateModel {
     // Determinations
     private func setupDeterminationsArray() {
         Task {
-            let ids = await self.fetchDeterminations()
+            let ids = await determinationStorage.fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
             await updateDeterminationsArray(with: ids)
         }
     }
 
-    private func fetchDeterminations() async -> [NSManagedObjectID] {
-        let results = await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: OrefDetermination.self,
-            onContext: backgroundContext,
-            predicate: NSPredicate.enactedDetermination,
-            key: "deliverAt",
-            ascending: false,
-            fetchLimit: 1
-        )
-
-        return await backgroundContext.perform {
-            return results.map(\.objectID)
-        }
-    }
-
     @MainActor private func updateDeterminationsArray(with IDs: [NSManagedObjectID]) {
         do {
             let determinationObjects = try IDs.compactMap { id in

+ 24 - 16
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -10,6 +10,7 @@ extension Home {
         @Injected() var broadcaster: Broadcaster!
         @Injected() var apsManager: APSManager!
         @Injected() var nightscoutManager: NightscoutManager!
+        @Injected() var determinationStorage: DeterminationStorage!
         private let timer = DispatchTimer(timeInterval: 5)
         private(set) var filteredHours = 24
         @Published var manualGlucose: [BloodGlucose] = []
@@ -689,8 +690,9 @@ extension Home.StateModel {
     // Setup Determinations
     private func setupDeterminationsArray() {
         Task {
-            async let enactedObjectIDs = fetchDeterminations(predicate: NSPredicate.enactedDetermination)
-            async let enactedAndNonEnactedObjectIDs = fetchDeterminations(
+            async let enactedObjectIDs = determinationStorage
+                .fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
+            async let enactedAndNonEnactedObjectIDs = determinationStorage.fetchLastDeterminationObjectID(
                 predicate: NSPredicate
                     .predicateFor30MinAgoForDetermination
             )
@@ -709,20 +711,6 @@ extension Home.StateModel {
         }
     }
 
-    private func fetchDeterminations(predicate: NSPredicate) async -> [NSManagedObjectID] {
-        let results = await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: OrefDetermination.self,
-            onContext: context,
-            predicate: predicate,
-            key: "deliverAt",
-            ascending: false,
-            fetchLimit: 1
-        )
-        return await context.perform {
-            results.map(\.objectID)
-        }
-    }
-
     @MainActor private func updateDeterminationsArray(
         with IDs: [NSManagedObjectID],
         keyPath: ReferenceWritableKeyPath<Home.StateModel, [OrefDetermination]>
@@ -967,3 +955,23 @@ extension Home.StateModel {
         }
     }
 }
+
+// MARK: Extension for Main Chart to draw Forecasts
+
+extension Home.StateModel {
+    func preprocessForecastData() -> [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)] {
+        determinationsFromPersistence
+            .compactMap { determination -> NSManagedObjectID? in
+                determination.objectID
+            }
+            .flatMap { determinationID -> [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)] in
+                let forecasts = determinationStorage.getForecasts(for: determinationID, in: viewContext)
+
+                return forecasts.flatMap { forecast in
+                    determinationStorage.getForecastValues(for: forecast.objectID, in: viewContext).map { forecastValue in
+                        (id: UUID(), forecast: forecast, forecastValue: forecastValue)
+                    }
+                }
+            }
+    }
+}

+ 1 - 51
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -447,42 +447,8 @@ extension MainChartView {
         return currentTime.addingTimeInterval(timeInterval)
     }
 
-    private func getForecasts(for determinationID: NSManagedObjectID, in context: NSManagedObjectContext) -> [Forecast] {
-        do {
-            guard let determination = try context.existingObject(with: determinationID) as? OrefDetermination,
-                  let forecastSet = determination.forecasts,
-                  let forecasts = Array(forecastSet) as? [Forecast]
-            else {
-                return []
-            }
-            return forecasts
-        } catch {
-            debugPrint(
-                "Failed \(DebuggingIdentifiers.failed) to fetch OrefDetermination with ID \(determinationID): \(error.localizedDescription)"
-            )
-            return []
-        }
-    }
-
-    private func getForecastValues(for forecastID: NSManagedObjectID, in context: NSManagedObjectContext) -> [ForecastValue] {
-        do {
-            guard let forecast = try context.existingObject(with: forecastID) as? Forecast,
-                  let forecastValueSet = forecast.forecastValues,
-                  let forecastValues = Array(forecastValueSet) as? [ForecastValue]
-            else {
-                return []
-            }
-            return forecastValues.sorted(by: { $0.index < $1.index })
-        } catch {
-            debugPrint(
-                "Failed \(DebuggingIdentifiers.failed) to fetch Forecast with ID \(forecastID): \(error.localizedDescription)"
-            )
-            return []
-        }
-    }
-
     private func drawForecasts() -> some ChartContent {
-        let preprocessedData = preprocessForecastData()
+        let preprocessedData = state.preprocessForecastData()
 
         return ForEach(preprocessedData, id: \.id) { tuple in
             let forecastValue = tuple.forecastValue
@@ -496,22 +462,6 @@ extension MainChartView {
         }
     }
 
-    private func preprocessForecastData() -> [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)] {
-        state.determinationsFromPersistence
-            .compactMap { determination -> NSManagedObjectID? in
-                determination.objectID
-            }
-            .flatMap { determinationID -> [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)] in
-                let forecasts = getForecasts(for: determinationID, in: context)
-
-                return forecasts.flatMap { forecast in
-                    getForecastValues(for: forecast.objectID, in: context).map { forecastValue in
-                        (id: UUID(), forecast: forecast, forecastValue: forecastValue)
-                    }
-                }
-            }
-    }
-
     private func drawCurrentTimeMarker() -> some ChartContent {
         RuleMark(
             x: .value(

+ 2 - 12
FreeAPS/Sources/Modules/ISFEditor/ISFEditorStateModel.swift

@@ -3,6 +3,7 @@ import SwiftUI
 
 extension ISFEditor {
     final class StateModel: BaseStateModel<Provider> {
+        @Injected() var determinationStorage: DeterminationStorage!
         @Published var items: [Item] = []
         private(set) var autosensISF: Decimal?
         private(set) var autosensRatio: Decimal = 0
@@ -99,22 +100,11 @@ extension ISFEditor {
 
         private func setupDeterminationsArray() {
             Task {
-                let ids = await self.fetchDeterminations()
+                let ids = await determinationStorage.fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
                 await updateDeterminationsArray(with: ids)
             }
         }
 
-        private func fetchDeterminations() async -> [NSManagedObjectID] {
-            CoreDataStack.shared.fetchEntities(
-                ofType: OrefDetermination.self,
-                onContext: context,
-                predicate: NSPredicate.enactedDetermination,
-                key: "deliverAt",
-                ascending: false,
-                fetchLimit: 1
-            ).map(\.objectID)
-        }
-
         @MainActor private func updateDeterminationsArray(with IDs: [NSManagedObjectID]) {
             do {
                 let objects = try IDs.compactMap { id in

+ 7 - 6
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -423,7 +423,7 @@ extension NightscoutAPI {
         }
     }
 
-    func uploadStatus(_ status: NightscoutStatus) -> AnyPublisher<Void, Swift.Error> {
+    func uploadStatus(_ status: NightscoutStatus) async throws {
         var components = URLComponents()
         components.scheme = url.scheme
         components.host = url.host
@@ -438,13 +438,14 @@ extension NightscoutAPI {
         if let secret = secret {
             request.addValue(secret.sha1(), forHTTPHeaderField: "api-secret")
         }
-        request.httpBody = try! JSONCoding.encoder.encode(status)
+        request.httpBody = try JSONCoding.encoder.encode(status)
         request.httpMethod = "POST"
 
-        return service.run(request)
-            .retry(Config.retryCount)
-            .map { _ in () }
-            .eraseToAnyPublisher()
+        let (data, response) = try await URLSession.shared.data(for: request)
+
+        guard let httpResponse = response as? HTTPURLResponse, (200 ... 299).contains(httpResponse.statusCode) else {
+            throw URLError(.badServerResponse)
+        }
     }
 
     func uploadPrefs(_ prefs: NightscoutPreferences) -> AnyPublisher<Void, Swift.Error> {

+ 12 - 59
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -13,7 +13,7 @@ protocol NightscoutManager: GlucoseSource {
     func deleteCarbs(withID id: String) async
     func deleteInsulin(withID id: String) async
     func deleteManualGlucose(withID id: String) async
-    func uploadStatus()
+    func uploadStatus() async
     func uploadGlucose() async
     func uploadManualGlucose() async
     func uploadStatistics(dailystat: Statistics) async
@@ -254,29 +254,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
-//    func uploadStatistics(dailystat: Statistics) {
-//        let stats = NightscoutStatistics(
-//            dailystats: dailystat
-//        )
-//
-//        guard let nightscout = nightscoutAPI, isUploadEnabled else {
-//            return
-//        }
-//
-//        processQueue.async {
-//            nightscout.uploadStats(stats)
-//                .sink { completion in
-//                    switch completion {
-//                    case .finished:
-//                        debug(.nightscout, "Statistics uploaded")
-//                    case let .failure(error):
-//                        debug(.nightscout, error.localizedDescription)
-//                    }
-//                } receiveValue: {}
-//                .store(in: &self.lifetime)
-//        }
-//    }
-
     func uploadPreferences(_ preferences: Preferences) {
         let prefs = NightscoutPreferences(
             preferences: settingsManager.preferences
@@ -357,27 +334,9 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
-    private func fetchDeterminations() {
-        let fetchRequest: NSFetchRequest<OrefDetermination> = OrefDetermination.fetchRequest()
-        fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \OrefDetermination.deliverAt, ascending: false)]
-        fetchRequest.predicate = NSPredicate.predicateFor30MinAgoForDetermination
-        fetchRequest.fetchLimit = 2
-
-        context.performAndWait {
-            do {
-                lastTwoDeterminations = try context.fetch(fetchRequest)
-                debugPrint(
-                    "Home State Model: \(#function) \(DebuggingIdentifiers.succeeded) fetched determinations from core data"
-                )
-            } catch {
-                debugPrint(
-                    "Home State Model: \(#function) \(DebuggingIdentifiers.failed) failed to fetch determinations from core data"
-                )
-            }
-        }
-    }
+    // TODO: - Fetch Determination here
 
-    func uploadStatus() {
+    func uploadStatus() async {
         let iob = storage.retrieve(OpenAPS.Monitor.iob, as: [IOBEntry].self)
 
         let penultimateDetermination = lastTwoDeterminations?.last
@@ -596,9 +555,9 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
         let pump = NSPumpStatus(clock: Date(), battery: battery, reservoir: reservoir, status: pumpStatus)
 
-        let device = UIDevice.current
+        let device = await UIDevice.current
 
-        let uploader = Uploader(batteryVoltage: nil, battery: Int(device.batteryLevel * 100))
+        let uploader = await Uploader(batteryVoltage: nil, battery: Int(device.batteryLevel * 100))
 
         var status: NightscoutStatus
 
@@ -615,21 +574,15 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
             return
         }
 
-        processQueue.async {
-            nightscout.uploadStatus(status)
-                .sink { completion in
-                    switch completion {
-                    case .finished:
-                        debug(.nightscout, "Status uploaded")
-                    case let .failure(error):
-                        debug(.nightscout, error.localizedDescription)
-                    }
-                } receiveValue: {}
-                .store(in: &self.lifetime)
+        do {
+            try await nightscout.uploadStatus(status)
+            debug(.nightscout, "Status uploaded")
+        } catch {
+            debug(.nightscout, error.localizedDescription)
         }
 
-        Task {
-            await uploadPodAge()
+        Task.detached {
+            await self.uploadPodAge()
         }
     }
 

+ 1 - 1
Model/Helper/Determination+helper.swift

@@ -24,6 +24,6 @@ extension OrefDetermination {
 extension NSPredicate {
     static var enactedDetermination: NSPredicate {
         let date = Date.halfHourAgo
-        return NSPredicate(format: "received == %@ AND deliverAt >= %@", true as NSNumber, date as NSDate)
+        return NSPredicate(format: "enacted == %@ AND deliverAt >= %@", true as NSNumber, date as NSDate)
     }
 }