Просмотр исходного кода

Merge branch 'core-data-sync-trio' of github.com:dnzxy/Open-iAPS into trio/settings-refactor

Deniz Cengiz 1 год назад
Родитель
Сommit
e0a3d0d368

+ 25 - 6
FreeAPS/Sources/APS/CGM/PluginSource.swift

@@ -135,13 +135,24 @@ extension PluginSource: CGMManagerDelegate {
         return glucoseStorage.lastGlucoseDate()
     }
 
-    func cgmManagerDidUpdateState(_: CGMManager) {
+    func cgmManagerDidUpdateState(_ cgmManager: CGMManager) {
         dispatchPrecondition(condition: .onQueue(processQueue))
-//        guard let g6Manager = manager as? TransmitterManager else {
-//            return
-//        }
-//        glucoseManager?.settingsManager.settings.uploadGlucose = g6Manager.shouldSyncToRemoteService
-//        UserDefaults.standard.dexcomTransmitterID = g6Manager.rawState["transmitterID"] as? String
+
+        guard let fetchGlucoseManager = glucoseManager else {
+            debug(
+                .deviceManager,
+                "Could not gracefully unwrap FetchGlucoseManager upon observing LoopKit's cgmManagerDidUpdateState"
+            )
+            return
+        }
+        // Adjust app-specific NS Upload setting value when CGM setting is changed
+        fetchGlucoseManager.settingsManager.settings.uploadGlucose = cgmManager.shouldSyncToRemoteService
+
+        fetchGlucoseManager.updateGlucoseSource(
+            cgmGlucoseSourceType: fetchGlucoseManager.settingsManager.settings.cgm,
+            cgmGlucosePluginId: fetchGlucoseManager.settingsManager.settings.cgmPluginIdentifier,
+            newManager: cgmManager as? CGMManagerUI
+        )
     }
 
     func credentialStoragePrefix(for _: CGMManager) -> String {
@@ -160,6 +171,14 @@ extension PluginSource: CGMManagerDelegate {
 
     private func readCGMResult(readingResult: CGMReadingResult) -> Result<[BloodGlucose], Error> {
         debug(.deviceManager, "PLUGIN CGM - Process CGM Reading Result launched with \(readingResult)")
+
+        if glucoseManager?.glucoseSource == nil {
+            debug(
+                .deviceManager,
+                "No glucose source available."
+            )
+        }
+
         switch readingResult {
         case let .newData(values):
 

+ 0 - 1
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -475,7 +475,6 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
         completion: @escaping (_ error: Error?) -> Void
     ) {
         dispatchPrecondition(condition: .onQueue(processQueue))
-        debug(.deviceManager, "New pump events:\n\(events.map(\.title).joined(separator: "\n"))")
 
         // filter buggy TBRs > maxBasal from MDT
         let events = events.filter {

+ 16 - 14
FreeAPS/Sources/APS/FetchGlucoseManager.swift

@@ -105,6 +105,7 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
         if self.cgmGlucoseSourceType != cgmGlucoseSourceType || self.cgmGlucosePluginId != cgmGlucosePluginId {
             removeCalibrations()
             cgmManager = nil
+            glucoseSource = nil
         }
 
         self.cgmGlucoseSourceType = cgmGlucoseSourceType
@@ -125,21 +126,22 @@ final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
             saveConfigManager()
         }
 
-        switch self.cgmGlucoseSourceType {
-        case .none:
-            glucoseSource = nil
-        case .xdrip:
-            glucoseSource = AppGroupSource(from: "xDrip", cgmType: .xdrip)
-        case .nightscout:
-            glucoseSource = nightscoutManager
-        case .simulator:
-            glucoseSource = simulatorSource
-        case .enlite:
-            glucoseSource = deviceDataManager
-        case .plugin:
-            glucoseSource = PluginSource(glucoseStorage: glucoseStorage, glucoseManager: self)
+        if glucoseSource == nil {
+            switch self.cgmGlucoseSourceType {
+            case .none:
+                glucoseSource = nil
+            case .xdrip:
+                glucoseSource = AppGroupSource(from: "xDrip", cgmType: .xdrip)
+            case .nightscout:
+                glucoseSource = nightscoutManager
+            case .simulator:
+                glucoseSource = simulatorSource
+            case .enlite:
+                glucoseSource = deviceDataManager
+            case .plugin:
+                glucoseSource = PluginSource(glucoseStorage: glucoseStorage, glucoseManager: self)
+            }
         }
-        // update the config
     }
 
     /// Upload cgmManager from raw value

+ 11 - 10
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -129,7 +129,7 @@ final class OpenAPS {
         let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: GlucoseStored.self,
             onContext: context,
-            predicate: NSPredicate.predicateForSixHoursAgo,
+            predicate: NSPredicate.predicateForOneDayAgoInMinutes,
             key: "date",
             ascending: false,
             fetchLimit: 72,
@@ -161,7 +161,7 @@ final class OpenAPS {
         let results = await CoreDataStack.shared.fetchEntitiesAsync(
             ofType: PumpEventStored.self,
             onContext: context,
-            predicate: NSPredicate.pumpHistoryLast24h,
+            predicate: NSPredicate.pumpHistoryLast1440Minutes,
             key: "timestamp",
             ascending: false,
             batchSize: 50
@@ -187,12 +187,15 @@ final class OpenAPS {
                 if let bolusDTO = event.toBolusDTOEnum() {
                     eventDTOs.append(bolusDTO)
                 }
-                if let tempBasalDTO = event.toTempBasalDTOEnum() {
-                    eventDTOs.append(tempBasalDTO)
-                }
+
                 if let tempBasalDurationDTO = event.toTempBasalDurationDTOEnum() {
                     eventDTOs.append(tempBasalDurationDTO)
                 }
+
+                if let tempBasalDTO = event.toTempBasalDTOEnum() {
+                    eventDTOs.append(tempBasalDTO)
+                }
+
                 return eventDTOs
             }
 
@@ -205,8 +208,7 @@ final class OpenAPS {
         debug(.openAPS, "Start determineBasal")
 
         // clock
-        let dateFormatted = OpenAPS.dateFormatter.string(from: clock)
-        let dateFormattedAsString = "\"\(dateFormatted)\""
+        self.storage.save(clock, as: Monitor.clock)
 
         // temp_basal
         let tempBasal = currentTemp.rawJSON
@@ -246,13 +248,12 @@ final class OpenAPS {
         )
 
         // TODO: - Save and fetch profile/basalProfile in/from UserDefaults!
-
         // Meal
         let meal = try await self.meal(
             pumphistory: pumpHistoryJSON,
             profile: profile,
             basalProfile: basalProfile,
-            clock: dateFormattedAsString,
+            clock: clock,
             carbs: carbsAsJSON,
             glucose: glucoseAsJSON
         )
@@ -261,7 +262,7 @@ final class OpenAPS {
         let iob = try await self.iob(
             pumphistory: pumpHistoryJSON,
             profile: profile,
-            clock: dateFormattedAsString,
+            clock: clock,
             autosens: autosens.isEmpty ? .null : autosens
         )
 

+ 2 - 14
FreeAPS/Sources/APS/Storage/DeterminationStorage.swift

@@ -100,13 +100,9 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
         var result: Determination?
 
         guard let determinationId = determinationIds.first else {
-            print("No determination ID found.")
             return nil
         }
 
-        print("Using context: \(backgroundContext)")
-        print("Determination ID: \(determinationId)")
-
         let predictions = Predictions(
             iob: await parseForecastValues(ofType: "iob", from: determinationId),
             zt: await parseForecastValues(ofType: "zt", from: determinationId),
@@ -118,15 +114,9 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
             do {
                 let orefDetermination = try self.backgroundContext.existingObject(with: determinationId) as? OrefDetermination
 
-                // Log the type of the fetched object
-                print("Fetched object type: \(type(of: orefDetermination))")
-                print("Fetched object description: \(orefDetermination)")
-
                 // Check if the fetched object is of the expected type
                 if let orefDetermination = orefDetermination {
-                    print("Successfully cast to OrefDetermination")
                     let forecastSet = orefDetermination.forecasts
-                    print("Fetched forecast set: \(forecastSet)")
 
                     result = Determination(
                         id: orefDetermination.id ?? UUID(),
@@ -160,12 +150,10 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
                         carbRatio: self.decimal(from: orefDetermination.carbRatio),
                         received: orefDetermination.enacted // this is actually part of NS...
                     )
-                } else {
-                    print("Fetched object is not of type OrefDetermination")
                 }
             } catch {
-                print("Failed to fetch managed object: \(error)")
-            }
+                debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch managed object with error: \(error.localizedDescription)")
+             }
 
             return result
         }

+ 1 - 5
FreeAPS/Sources/APS/Storage/GlucoseStorage.swift

@@ -46,8 +46,6 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
 
     func storeGlucose(_ glucose: [BloodGlucose]) {
         processQueue.sync {
-            debug(.deviceManager, "Start storage of glucose data")
-
             self.coredataContext.perform {
                 let datesToCheck: Set<Date?> = Set(glucose.compactMap { $0.dateString as Date? })
                 let fetchRequest: NSFetchRequest<NSFetchRequestResult> = GlucoseStored.fetchRequest()
@@ -81,8 +79,6 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
                         glucoseEntry.date = entry.dateString
                         glucoseEntry.direction = entry.direction?.rawValue
                         glucoseEntry.isUploadedToNS = false /// the value is not uploaded to NS (yet)
-                        debugPrint("\(DebuggingIdentifiers.failed)")
-                        debugPrint("\(String(describing: glucoseEntry.direction))")
                         return false // Continue processing
                     }
                 )
@@ -90,7 +86,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
                 // process batch insert
                 do {
                     try self.coredataContext.execute(batchInsert)
-                    debugPrint("Glucose Storage: \(#function) \(DebuggingIdentifiers.succeeded) saved glucose to Core Data")
+//                    debugPrint("Glucose Storage: \(#function) \(DebuggingIdentifiers.succeeded) saved glucose to Core Data")
 
                     // Send notification for triggering a fetch in Home State Model to update the Glucose Array
                     /// This is necessary because changes only get merged automatically into the viewContext because of the Persistent History Tracking

+ 0 - 3
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -1001,9 +1001,6 @@ extension MainChartView {
 
         minValue = minOverall * conversionFactor - 50 * conversionFactor
         maxValue = maxOverall * conversionFactor + 80 * conversionFactor
-
-        debug(.default, "min \(minValue)")
-        debug(.default, "max \(maxValue)")
     }
 
     private func yAxisChartDataCobChart() {

+ 3 - 32
FreeAPS/Sources/Services/HealthKit/HealthKitManager.swift

@@ -168,14 +168,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
                 }
 
             healthKitStore.save(samplesToSave) { (success: Bool, error: Error?) -> Void in
-                if success {
-                    for sample in samplesToSave {
-                        debug(
-                            .service,
-                            "Stored blood glucose \(sample.quantity) in HealthKit Store! Metadata: \(String(describing: sample.metadata?.values))"
-                        )
-                    }
-                } else {
+                if !success {
                     debug(.service, "Failed to store blood glucose in HealthKit Store!")
                     debug(.service, error?.localizedDescription ?? "Unknown error")
                 }
@@ -222,14 +215,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
                 }
 
             healthKitStore.save(samplesToSave) { (success: Bool, error: Error?) -> Void in
-                if success {
-                    for sample in samplesToSave {
-                        debug(
-                            .service,
-                            "Stored carb entry \(sample.quantity) in HealthKit Store! Metadata: \(String(describing: sample.metadata?.values))"
-                        )
-                    }
-                } else {
+                if !success {
                     debug(.service, "Failed to store carb entry in HealthKit Store!")
                     debug(.service, error?.localizedDescription ?? "Unknown error")
                 }
@@ -298,14 +284,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
                 }
 
             healthKitStore.save(bolusSamples + basalSamples) { (success: Bool, error: Error?) -> Void in
-                if success {
-                    for sample in bolusSamples + basalSamples {
-                        debug(
-                            .service,
-                            "Stored insulin entry in HealthKit Store! Metadata: \(String(describing: sample.metadata?.values))"
-                        )
-                    }
-                } else {
+                if !success {
                     debug(.service, "Failed to store insulin entry in HealthKit Store!")
                     debug(.service, error?.localizedDescription ?? "Unknown error")
                 }
@@ -493,7 +472,6 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
 
     private func prepareBGSamplesToPublisherFetch(_ samples: [HKQuantitySample]) {
         dispatchPrecondition(condition: .onQueue(processQueue))
-        debug(.service, "Start preparing samples: \(String(describing: samples))")
 
         newGlucose += samples
             .compactMap { sample -> HealthKitSample? in
@@ -522,11 +500,6 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             .filter { $0.dateString >= Date().addingTimeInterval(-1.days.timeInterval) }
 
         newGlucose = newGlucose.removeDublicates()
-
-        debug(
-            .service,
-            "Current BloodGlucose.Type objects will be send from Publisher during fetch: \(String(describing: newGlucose))"
-        )
     }
 
     // MARK: - GlucoseSource
@@ -542,9 +515,7 @@ final class BaseHealthKitManager: HealthKitManager, Injectable, CarbsObserver, P
             }
 
             self.processQueue.async {
-                //   debug(.service, "Start fetching HealthKitManager")
                 guard self.settingsManager.settings.useAppleHealth else {
-                    debug(.service, "HealthKitManager cant return any data, because useAppleHealth option is disable")
                     promise(.success([]))
                     return
                 }

+ 11 - 11
FreeAPS/Sources/Services/Network/NightscoutAPI.swift

@@ -344,8 +344,8 @@ extension NightscoutAPI {
         do {
             let encodedBody = try JSONCoding.encoder.encode(treatments)
             request.httpBody = encodedBody
-            debugPrint("Payload treatments size: \(encodedBody.count) bytes")
-            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
+//            debugPrint("Payload treatments size: \(encodedBody.count) bytes")
+//            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
         } catch {
             debugPrint("Error encoding payload: \(error.localizedDescription)")
             throw error
@@ -359,7 +359,7 @@ extension NightscoutAPI {
             throw URLError(.badServerResponse)
         }
 
-        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
+//        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
     }
 
     func uploadGlucose(_ glucose: [BloodGlucose]) async throws {
@@ -380,8 +380,8 @@ extension NightscoutAPI {
         do {
             let encodedBody = try JSONCoding.encoder.encode(glucose)
             request.httpBody = encodedBody
-            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
-            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
+//            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
+//            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
         } catch {
             debugPrint("Error encoding payload: \(error.localizedDescription)")
             throw error
@@ -395,7 +395,7 @@ extension NightscoutAPI {
             throw URLError(.badServerResponse)
         }
 
-        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
+//        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
     }
 
     func uploadStats(_ stats: NightscoutStatistics) async throws {
@@ -442,8 +442,8 @@ extension NightscoutAPI {
         do {
             let encodedBody = try JSONCoding.encoder.encode(status)
             request.httpBody = encodedBody
-            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
-            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
+//            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
+//            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
         } catch {
             debugPrint("Error encoding payload: \(error.localizedDescription)")
             throw error
@@ -572,8 +572,8 @@ extension NightscoutAPI {
         do {
             let encodedBody = try JSONCoding.encoder.encode(overrides)
             request.httpBody = encodedBody
-            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
-            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
+//            debugPrint("Payload glucose size: \(encodedBody.count) bytes")
+//            debugPrint(String(data: encodedBody, encoding: .utf8) ?? "Invalid payload")
         } catch {
             debugPrint("Error encoding payload: \(error.localizedDescription)")
             throw error
@@ -587,7 +587,7 @@ extension NightscoutAPI {
             throw URLError(.badServerResponse)
         }
 
-        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
+//        debugPrint("Upload successful, response data: \(String(data: data, encoding: .utf8) ?? "No data")")
     }
 }
 

+ 0 - 14
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -482,13 +482,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateOrefDeterminationAsUploaded(_ determination: [Determination]) async {
         await backgroundContext.perform {
             let ids = determination.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<OrefDetermination> = OrefDetermination.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -737,13 +735,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateGlucoseAsUploaded(_ glucose: [BloodGlucose]) async {
         await backgroundContext.perform {
             let ids = glucose.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<GlucoseStored> = GlucoseStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -780,13 +776,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateTreatmentsAsUploaded(_ treatments: [NightscoutTreatment]) async {
         await backgroundContext.perform {
             let ids = treatments.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<PumpEventStored> = PumpEventStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -823,13 +817,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateManualGlucoseAsUploaded(_ treatments: [NightscoutTreatment]) async {
         await backgroundContext.perform {
             let ids = treatments.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<GlucoseStored> = GlucoseStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -866,13 +858,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateCarbsAsUploaded(_ treatments: [NightscoutTreatment]) async {
         await backgroundContext.perform {
             let ids = treatments.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<CarbEntryStored> = CarbEntryStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -909,13 +899,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateOverridesAsUploaded(_ overrides: [NightscoutExercise]) async {
         await backgroundContext.perform {
             let ids = overrides.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<OverrideStored> = OverrideStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }
@@ -952,13 +940,11 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private func updateOverrideRunsAsUploaded(_ overrideRuns: [NightscoutExercise]) async {
         await backgroundContext.perform {
             let ids = overrideRuns.map(\.id) as NSArray
-            print("\(DebuggingIdentifiers.inProgress) ids: \(ids)")
             let fetchRequest: NSFetchRequest<OverrideRunStored> = OverrideRunStored.fetchRequest()
             fetchRequest.predicate = NSPredicate(format: "id IN %@", ids)
 
             do {
                 let results = try self.backgroundContext.fetch(fetchRequest)
-                print("\(DebuggingIdentifiers.inProgress) results: \(results)")
                 for result in results {
                     result.isUploadedToNS = true
                 }

+ 1 - 1
FreeAPS/Sources/Services/UserNotifications/UserNotificationsManager.swift

@@ -240,7 +240,7 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
 
             guard let lastReading = glucoseObjects.first?.glucose,
                   let secondLastReading = glucoseObjects.dropFirst().first?.glucose,
-                  let lastDirection = glucoseObjects.first?.direction else { return }
+                  let lastDirection = glucoseObjects.first?.directionEnum?.symbol else { return }
 
             addAppBadge(glucose: (glucoseObjects.first?.glucose).map { Int($0) })
 

+ 1 - 1
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -199,7 +199,7 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
                 let value = settingsManager.settings
                     .units == .mgdL ? Decimal(firstGlucoseValue.glucose) : Decimal(firstGlucoseValue.glucose).asMmolL
                 state.glucose = glucoseFormatter.string(from: value as NSNumber)
-                state.trend = firstGlucoseValue.direction
+                state.trend = firstGlucoseValue.directionEnum?.symbol
                 let delta = glucoseValues
                     .count >= 2 ? Decimal(firstGlucoseValue.glucose) - Decimal(glucoseValues.dropFirst().first?.glucose ?? 0) : 0
                 let deltaConverted = settingsManager.settings.units == .mgdL ? delta : delta.asMmolL

+ 12 - 14
Model/CoreDataStack.swift

@@ -106,7 +106,7 @@ class CoreDataStack: ObservableObject {
     private func fetchPersistentHistoryTransactionsAndChanges() async throws {
         let taskContext = newTaskContext()
         taskContext.name = "persistentHistoryContext"
-        debugPrint("Start fetching persistent history changes from the store ... \(DebuggingIdentifiers.inProgress)")
+//        debugPrint("Start fetching persistent history changes from the store ... \(DebuggingIdentifiers.inProgress)")
 
         try await taskContext.perform {
             // Execute the persistent history change since the last transaction
@@ -121,7 +121,7 @@ class CoreDataStack: ObservableObject {
     }
 
     private func mergePersistentHistoryChanges(from history: [NSPersistentHistoryTransaction]) {
-        debugPrint("Received \(history.count) persistent history transactions")
+//        debugPrint("Received \(history.count) persistent history transactions")
         // Update view context with objectIDs from history change request
         /// - Tag: mergeChanges
         let viewContext = persistentContainer.viewContext
@@ -210,7 +210,7 @@ extension CoreDataStack {
 
             // Guard check if there are NSManagedObjects older than the specified days
             guard !objectIDs.isEmpty else {
-                debugPrint("No objects found older than \(days) days.")
+//                debugPrint("No objects found older than \(days) days.")
                 return
             }
 
@@ -258,7 +258,7 @@ extension CoreDataStack {
             }
 
             guard !parentObjectIDs.isEmpty else {
-                debugPrint("No \(parentType) objects found older than \(days) days.")
+//                debugPrint("No \(parentType) objects found older than \(days) days.")
                 return
             }
 
@@ -272,7 +272,7 @@ extension CoreDataStack {
             }
 
             guard !childObjectIDs.isEmpty else {
-                debugPrint("No \(childType) objects found related to \(parentType) objects older than \(days) days.")
+//                debugPrint("No \(childType) objects found related to \(parentType) objects older than \(days) days.")
                 return
             }
 
@@ -339,9 +339,9 @@ extension CoreDataStack {
         /// we need to ensure that the fetch immediately returns a value as long as the whole app does not use the async await pattern, otherwise we could perform this asynchronously with backgroundContext.perform and not block the thread
         context.performAndWait {
             do {
-                debugPrint(
-                    "Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.succeeded) on Thread: \(Thread.current)"
-                )
+//                debugPrint(
+//                    "Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.succeeded) on Thread: \(Thread.current)"
+//                )
                 result = try context.fetch(request)
             } catch let error as NSError {
                 debugPrint(
@@ -387,9 +387,7 @@ extension CoreDataStack {
 
         return await context.perform {
             do {
-                debugPrint(
-                    "Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.succeeded) on Thread: \(Thread.current)"
-                )
+//                debugPrint("Fetching \(T.self) in \(callingFunction) from \(callingClass): \(DebuggingIdentifiers.succeeded) on Thread: \(Thread.current)")
                 return try context.fetch(request)
             } catch let error as NSError {
                 debugPrint(
@@ -429,9 +427,9 @@ extension NSManagedObjectContext {
         do {
             guard onContext.hasChanges else { return }
             try onContext.save()
-            debugPrint(
-                "Saving to Core Data successful in \(callingFunction) in \(callingClass): \(DebuggingIdentifiers.succeeded)"
-            )
+//            debugPrint(
+//                "Saving to Core Data successful in \(callingFunction) in \(callingClass): \(DebuggingIdentifiers.succeeded)"
+//            )
         } catch let error as NSError {
             debugPrint(
                 "Saving to Core Data failed in \(callingFunction) in \(callingClass): \(DebuggingIdentifiers.failed) with error \(error), \(error.userInfo)"

+ 9 - 0
Model/Helper/NSPredicates.swift

@@ -6,6 +6,10 @@ extension Date {
         Calendar.current.startOfDay(for: Date())
     }
 
+    static var oneDayAgoInMinutes: Date {
+        Calendar.current.date(byAdding: .minute, value: -1440, to: Date())!
+    }
+
     static var oneDayAgo: Date {
         Calendar.current.date(byAdding: .day, value: -1, to: Date())!
     }
@@ -48,6 +52,11 @@ extension NSPredicate {
 
     static let none = NSPredicate(format: "FALSEPREDICATE")
 
+    static var predicateForOneDayAgoInMinutes: NSPredicate {
+        let date = Date.oneDayAgoInMinutes
+        return NSPredicate(format: "date >= %@", date as NSDate)
+    }
+
     static var predicateForOneDayAgo: NSPredicate {
         let date = Date.oneDayAgo
         return NSPredicate(format: "date >= %@", date as NSDate)

+ 8 - 3
Model/Helper/PumpEvent+helper.swift

@@ -53,6 +53,11 @@ public extension PumpEventStored {
 }
 
 extension NSPredicate {
+    static var pumpHistoryLast1440Minutes: NSPredicate {
+        let date = Date.oneDayAgoInMinutes
+        return NSPredicate(format: "timestamp >= %@", date as NSDate)
+    }
+
     static var pumpHistoryLast24h: NSPredicate {
         let date = Date.oneDayAgo
         return NSPredicate(format: "timestamp >= %@", date as NSDate)
@@ -155,7 +160,7 @@ extension PumpEventStored {
     }
 
     func toTempBasalDTOEnum() -> PumpEventDTO? {
-        guard let timestamp = timestamp, let tempBasal = tempBasal, let rate = tempBasal.rate else {
+        guard let id = id, let timestamp = timestamp, let tempBasal = tempBasal, let rate = tempBasal.rate else {
             return nil
         }
 
@@ -169,12 +174,12 @@ extension PumpEventStored {
     }
 
     func toTempBasalDurationDTOEnum() -> PumpEventDTO? {
-        guard let timestamp = timestamp, let tempBasal = tempBasal else {
+        guard let id = id, let timestamp = timestamp, let tempBasal = tempBasal else {
             return nil
         }
 
         let tempBasalDurationDTO = TempBasalDurationDTO(
-            id: id ?? UUID().uuidString,
+            id: id,
             timestamp: PumpEventStored.dateFormatter.string(from: timestamp),
             duration: Int(tempBasal.duration)
         )

+ 1 - 55
Trio.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -1,5 +1,5 @@
 {
-  "originHash" : "59ac7eba66375d6eb406e758cb0b9964f4b3b0ae45c5665596f00384c32262b9",
+  "originHash" : "cef813f4bbb01679d4ac9bf4a9f82c1a0a61e44dc839643e81aa92e4d00642bc",
   "pins" : [
     {
       "identity" : "cryptoswift",
@@ -11,15 +11,6 @@
       }
     },
     {
-      "identity" : "mkringprogressview",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/maxkonovalov/MKRingProgressView.git",
-      "state" : {
-        "branch" : "master",
-        "revision" : "660888aab1d2ab0ed7eb9eb53caec12af4955fa7"
-      }
-    },
-    {
       "identity" : "slidebutton",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/no-comment/SlideButton",
@@ -29,24 +20,6 @@
       }
     },
     {
-      "identity" : "swift-algorithms",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/apple/swift-algorithms",
-      "state" : {
-        "revision" : "2327673b0e9c7e90e6b1826376526ec3627210e4",
-        "version" : "0.2.1"
-      }
-    },
-    {
-      "identity" : "swift-numerics",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/apple/swift-numerics",
-      "state" : {
-        "revision" : "6583ac70c326c3ee080c1d42d9ca3361dca816cd",
-        "version" : "0.1.0"
-      }
-    },
-    {
       "identity" : "swiftcharts",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/ivanschuetz/SwiftCharts.git",
@@ -56,33 +29,6 @@
       }
     },
     {
-      "identity" : "swiftdate",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/malcommac/SwiftDate",
-      "state" : {
-        "revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
-        "version" : "6.3.1"
-      }
-    },
-    {
-      "identity" : "swiftmessages",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/SwiftKickMobile/SwiftMessages",
-      "state" : {
-        "revision" : "62e12e138fc3eedf88c7553dd5d98712aa119f40",
-        "version" : "9.0.9"
-      }
-    },
-    {
-      "identity" : "swinject",
-      "kind" : "remoteSourceControl",
-      "location" : "https://github.com/Swinject/Swinject",
-      "state" : {
-        "revision" : "be9dbcc7b86811bc131539a20c6f9c2d3e56919f",
-        "version" : "2.9.1"
-      }
-    },
-    {
       "identity" : "tidepoolkit",
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/tidepool-org/TidepoolKit",

+ 1 - 6
scripts/capture-build-details.sh

@@ -1,22 +1,17 @@
 #!/bin/sh -e
-
 #  capture-build-details.sh
 #  Trio
 #
 #  Created by Jonas Björkert on 2024-05-08.
-
 # Enable debugging if needed
 #set -x
-
 info_plist_path="${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/BuildDetails.plist"
-
 # Ensure the path to BuildDetails.plist is valid.
 if [ "${info_plist_path}" == "/" -o ! -e "${info_plist_path}" ]; then
     echo "BuildDetails.plist file does not exist at path: ${info_plist_path}" >&2
     exit 1
 else
     echo "Gathering build details..."
-
     # Capture the current date and write it to BuildDetails.plist
     plutil -replace com-trio-build-date -string "$(date)" "${info_plist_path}"
 
@@ -40,4 +35,4 @@ else
 
     # Update BuildDetails.plist with the SHA information
     plutil -replace com-trio-commit-sha -string "${git_commit_sha}" "${info_plist_path}"
-fi
+fi