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

Determinations in NSDeviceStatus WIP

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

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

@@ -724,7 +724,6 @@ final class BaseAPSManager: APSManager, Injectable {
     }
 
     private func reportEnacted(wasEnacted: Bool) async {
-
         guard let determinationID = await determinationStorage
             .fetchLastDeterminationObjectID(predicate: NSPredicate.predicateFor30MinAgoForDetermination).first
         else {

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

@@ -41,7 +41,7 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
             return forecasts
         } catch {
             debugPrint(
-                "Failed \(DebuggingIdentifiers.failed) to fetch OrefDetermination with ID \(determinationID): \(error.localizedDescription)"
+                "Failed \(DebuggingIdentifiers.failed) to fetch Forecasts OrefDetermination with ID \(determinationID): \(error.localizedDescription)"
             )
             return []
         }
@@ -58,7 +58,7 @@ final class BaseDeterminationStorage: DeterminationStorage, Injectable {
             return forecastValues.sorted(by: { $0.index < $1.index })
         } catch {
             debugPrint(
-                "Failed \(DebuggingIdentifiers.failed) to fetch Forecast with ID \(forecastID): \(error.localizedDescription)"
+                "Failed \(DebuggingIdentifiers.failed) to fetch Forecast Values with ID \(forecastID): \(error.localizedDescription)"
             )
             return []
         }

+ 81 - 129
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -24,6 +24,7 @@ protocol NightscoutManager: GlucoseSource {
 
 final class BaseNightscoutManager: NightscoutManager, Injectable {
     @Injected() private var keychain: Keychain!
+    @Injected() private var determinationStorage: DeterminationStorage!
     @Injected() private var glucoseStorage: GlucoseStorage!
     @Injected() private var tempTargetsStorage: TempTargetsStorage!
     @Injected() private var overridesStorage: OverrideStorage!
@@ -335,156 +336,107 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
-
-    private func fetchEnactedDetermination() async -> [OrefDetermination] {
-        let enactedDeterminations = await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: OrefDetermination.self,
-            onContext: backgroundContext,
-            predicate: NSPredicate.enactedDetermination,
-            key: "deliverAt",
-            ascending: false,
-            fetchLimit: 1
-        )
-
-        let enactedIds = await backgroundContext.perform {
-            enactedDeterminations.map(\.objectID)
+    func parseOrefDetermination(_ determinationIds: [NSManagedObjectID]) -> Determination? {
+        // Convert NSDecimalNumber to Decimal
+        func decimal(from nsDecimalNumber: NSDecimalNumber?) -> Decimal {
+            nsDecimalNumber?.decimalValue ?? 0.0
         }
 
-        return await context.perform {
-            do {
-                let enacted = try enactedIds.compactMap { id in
-                    try self.context.existingObject(with: id) as? OrefDetermination
-                }
-
-                debugPrint(
-                    "NightscoutManager \(#function) \(DebuggingIdentifiers.succeeded) fetched ENACTED determinations: \(String(describing: enacted))"
-                )
+        // Convert NSSet to array of Ints for Predictions
+        func parseForecastValues(ofType _: String, from orefDetermination: OrefDetermination) -> [Int]? {
+            let determinationID = orefDetermination.objectID
+            let forecasts = determinationStorage.getForecasts(for: determinationID, in: context)
 
-                return enacted
-            } catch {
-                debugPrint(
-                    "NightscoutManager \(#function) \(DebuggingIdentifiers.failed) error while fetching the determinations: \(error.localizedDescription)"
-                )
-                return []
+            return forecasts.flatMap { forecast in
+                determinationStorage.getForecastValues(for: forecast.objectID, in: context).map { forecastValue in
+                    Int(forecastValue.value)
+                }
             }
         }
-    }
 
-    private func fetchSuggestedDetermination() async -> [OrefDetermination] {
-        let suggestedDeterminations = await CoreDataStack.shared.fetchEntitiesAsync(
-            ofType: OrefDetermination.self,
-            onContext: backgroundContext,
-            predicate: NSPredicate(
-                format: "(enacted == %@ OR enacted == NULL) AND deliverAt >= %@",
-                false as NSNumber,
-                Date.halfHourAgo as NSDate
-            ),
-            key: "deliverAt",
-            ascending: false,
-            fetchLimit: 1
-        )
+        var result: Determination?
 
-        let suggestedIds = await backgroundContext.perform {
-            suggestedDeterminations.map(\.objectID)
+        guard let determinationId = determinationIds.first else {
+            print("No determination ID found.")
+            return nil
         }
 
-        return await context.perform {
-            do {
-                let suggested = try suggestedIds.compactMap { id in
-                    try self.context.existingObject(with: id) as? OrefDetermination
-                }
+        print("Using context: \(backgroundContext)")
+        print("Determination ID: \(determinationId)")
 
-                debugPrint(
-                    "NightscoutManager \(#function) \(DebuggingIdentifiers.succeeded) fetched SUGGESTED determinations: \(String(describing: suggested))"
+        do {
+            let orefDetermination = try backgroundContext.existingObject(with: determinationId)
+
+            // 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 as? OrefDetermination {
+                print("Successfully cast to OrefDetermination")
+                let forecastSet = orefDetermination.forecasts
+                print("Fetched forecast set: \(forecastSet)")
+
+                let predictions = Predictions(
+                    iob: parseForecastValues(ofType: "iob", from: orefDetermination),
+                    zt: parseForecastValues(ofType: "zt", from: orefDetermination),
+                    cob: parseForecastValues(ofType: "cob", from: orefDetermination),
+                    uam: parseForecastValues(ofType: "uam", from: orefDetermination)
                 )
 
-                return suggested
-            } catch {
-                debugPrint(
-                    "NightscoutManager \(#function) \(DebuggingIdentifiers.failed) error while fetching the determinations: \(error.localizedDescription)"
+                result = Determination(
+                    reason: orefDetermination.reason ?? "",
+                    units: orefDetermination.smbToDeliver as Decimal?,
+                    insulinReq: decimal(from: orefDetermination.insulinReq),
+                    eventualBG: orefDetermination.eventualBG as? Int,
+                    sensitivityRatio: decimal(from: orefDetermination.sensitivityRatio),
+                    rate: decimal(from: orefDetermination.rate),
+                    duration: decimal(from: orefDetermination.duration),
+                    iob: decimal(from: orefDetermination.iob),
+                    cob: orefDetermination.cob != 0 ? Decimal(orefDetermination.cob) : nil,
+                    predictions: predictions,
+                    deliverAt: orefDetermination.deliverAt,
+                    carbsReq: orefDetermination.carbsRequired != 0 ? Decimal(orefDetermination.carbsRequired) : nil,
+                    temp: TempType(rawValue: orefDetermination.temp ?? "absolute"),
+                    bg: decimal(from: orefDetermination.glucose),
+                    reservoir: decimal(from: orefDetermination.reservoir),
+                    isf: decimal(from: orefDetermination.insulinSensitivity),
+                    timestamp: orefDetermination.timestamp,
+                    tdd: decimal(from: orefDetermination.totalDailyDose),
+                    insulin: nil,
+                    current_target: decimal(from: orefDetermination.currentTarget),
+                    insulinForManualBolus: decimal(from: orefDetermination.insulinForManualBolus),
+                    manualBolusErrorString: decimal(from: orefDetermination.manualBolusErrorString),
+                    minDelta: decimal(from: orefDetermination.minDelta),
+                    expectedDelta: decimal(from: orefDetermination.expectedDelta),
+                    minGuardBG: nil,
+                    minPredBG: nil,
+                    threshold: decimal(from: orefDetermination.threshold),
+                    carbRatio: decimal(from: orefDetermination.carbRatio)
                 )
-
-                return []
-            }
-        }
-    }
-
-    func parseOrefDetermination(_ orefDetermination: OrefDetermination) -> Determination {
-        // Convert NSDecimalNumber to Decimal
-        func decimal(from nsDecimalNumber: NSDecimalNumber?) -> Decimal? {
-            nsDecimalNumber?.decimalValue
-        }
-
-        // Convert NSSet to array of Ints for Predictions
-        func parseForecastValues(ofType type: String, from orefDetermination: OrefDetermination) -> [Int]? {
-            guard let forecasts = orefDetermination.forecasts?.filter({ ($0 as? Forecast)?.type == type }) as? [Forecast] else {
-                return nil
-            }
-
-            return forecasts.flatMap { forecast in
-                (forecast.forecastValues as? [ForecastValue])?.map { Int($0.value) } ?? []
+            } else {
+                print("Fetched object is not of type OrefDetermination")
             }
+        } catch {
+            print("Failed to fetch managed object: \(error)")
         }
 
-        // Parse Insulin data
-        let insulin = Insulin(
-            TDD: decimal(from: orefDetermination.totalDailyDose),
-            bolus: orefDetermination.bolus as Decimal?,
-            temp_basal: orefDetermination.tempBasal as Decimal?,
-            scheduled_basal: orefDetermination.scheduledBasal as Decimal?
-        )
-
-        // Parse Predictions data
-        let predictions = Predictions(
-            iob: parseForecastValues(ofType: "iob", from: orefDetermination),
-            zt: parseForecastValues(ofType: "zt", from: orefDetermination),
-            cob: parseForecastValues(ofType: "cob", from: orefDetermination),
-            uam: parseForecastValues(ofType: "uam", from: orefDetermination)
-        )
-
-        return Determination(
-            reason: orefDetermination.reason ?? "",
-            units: orefDetermination.smbToDeliver as Decimal?,
-            insulinReq: decimal(from: orefDetermination.insulinReq),
-            eventualBG: orefDetermination.eventualBG as? Int,
-            sensitivityRatio: decimal(from: orefDetermination.sensitivityRatio),
-            rate: decimal(from: orefDetermination.rate),
-            duration: decimal(from: orefDetermination.duration),
-            iob: decimal(from: orefDetermination.iob),
-            cob: orefDetermination.cob != 0 ? Decimal(orefDetermination.cob) : nil,
-            predictions: predictions,
-            deliverAt: orefDetermination.deliverAt,
-            carbsReq: orefDetermination.carbsRequired != 0 ? Decimal(orefDetermination.carbsRequired) : nil,
-            temp: TempType(rawValue: orefDetermination.temp ?? "absolute"),
-            bg: decimal(from: orefDetermination.glucose),
-            reservoir: decimal(from: orefDetermination.reservoir),
-            isf: decimal(from: orefDetermination.insulinSensitivity),
-            timestamp: orefDetermination.timestamp, // Assuming you have this property
-            tdd: decimal(from: orefDetermination.totalDailyDose),
-            insulin: insulin,
-            current_target: decimal(from: orefDetermination.currentTarget),
-            insulinForManualBolus: decimal(from: orefDetermination.insulinForManualBolus),
-            manualBolusErrorString: decimal(from: orefDetermination.manualBolusErrorString),
-            minDelta: decimal(from: orefDetermination.minDelta),
-            expectedDelta: decimal(from: orefDetermination.expectedDelta),
-            minGuardBG: nil,
-            minPredBG: nil,
-            threshold: decimal(from: orefDetermination.threshold),
-            carbRatio: decimal(from: orefDetermination.carbRatio)
-        )
+        return result
     }
 
     func uploadStatus() async {
-        let enactedFromPersistence = await fetchEnactedDetermination()
-        let suggestedFromPersistence = await fetchSuggestedDetermination()
-
         var enacted: Determination?
         var suggested: Determination?
-
-        if let lastEnacted = enactedFromPersistence.first, let lastSuggested = suggestedFromPersistence.first {
-            enacted = parseOrefDetermination(lastEnacted)
-            suggested = parseOrefDetermination(lastSuggested)
-        }
+//        let enacted = parseOrefDetermination(
+//            await determinationStorage
+//                .fetchLastDeterminationObjectID(predicate: NSPredicate.enactedDetermination)
+//        )
+//
+//        let suggested = parseOrefDetermination(await determinationStorage.fetchLastDeterminationObjectID(predicate: NSPredicate(
+//            format: "(enacted == %@ OR enacted == NULL) AND deliverAt >= %@",
+//            false as NSNumber,
+//            Date.halfHourAgo as NSDate
+//        )))
 
         let iob = storage.retrieve(OpenAPS.Monitor.iob, as: [IOBEntry].self)