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

Merge branch 'forecast-chart' of github.com:polscm32/Open-iAPS into forecast-chart

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

+ 13 - 15
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -60,6 +60,7 @@ struct MainChartView: View {
     @State private var count: Decimal = 1
     @State private var startMarker =
         Date(timeIntervalSinceNow: TimeInterval(hours: -24))
+    @State private var endMarker = Date(timeIntervalSinceNow: TimeInterval(hours: 3))
     @State private var minValue: Decimal = 45
     @State private var maxValue: Decimal = 270
     @State private var selection: Date? = nil
@@ -75,20 +76,6 @@ struct MainChartView: View {
     @Environment(\.colorScheme) var colorScheme
     @Environment(\.calendar) var calendar
 
-    private var endMarker: Date {
-        let threeHourSinceNow = Date(timeIntervalSinceNow: TimeInterval(hours: 3))
-
-        // min is 1.5h -> (1.5*1h = 1.5*(5*12*60))
-        let dynamicFutureDateForCone = Date(timeIntervalSinceNow: TimeInterval(
-            Int(1.5) * 5 * state
-                .minCount * 60
-        ))
-
-        return state
-            .displayForecastsAsLines ? threeHourSinceNow : dynamicFutureDateForCone <= threeHourSinceNow ?
-            dynamicFutureDateForCone.addingTimeInterval(TimeInterval(minutes: 30)) : threeHourSinceNow
-    }
-
     private var bolusFormatter: NumberFormatter {
         let formatter = NumberFormatter()
         formatter.numberStyle = .decimal
@@ -1124,7 +1111,18 @@ extension MainChartView {
     /// update start and  end marker to fix scroll update problem with x axis
     private func updateStartEndMarkers() {
         startMarker = Date(timeIntervalSince1970: TimeInterval(NSDate().timeIntervalSince1970 - 86400))
-//        endMarker = Date(timeIntervalSince1970: TimeInterval(NSDate().timeIntervalSince1970 + 10800))
+
+        let threeHourSinceNow = Date(timeIntervalSinceNow: TimeInterval(hours: 3))
+
+        // min is 1.5h -> (1.5*1h = 1.5*(5*12*60))
+        let dynamicFutureDateForCone = Date(timeIntervalSinceNow: TimeInterval(
+            Int(1.5) * 5 * state
+                .minCount * 60
+        ))
+
+        endMarker = state
+            .displayForecastsAsLines ? threeHourSinceNow : dynamicFutureDateForCone <= threeHourSinceNow ?
+            dynamicFutureDateForCone.addingTimeInterval(TimeInterval(minutes: 30)) : threeHourSinceNow
     }
 
     private func calculateBasals() {

+ 103 - 95
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -67,6 +67,7 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
         setupNotification()
         coreDataObserver = CoreDataObserver()
         registerHandlers()
+
         Task {
             await configureState()
         }
@@ -91,10 +92,6 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
             }
             return data
         }
-
-        Task {
-            await configureState()
-        }
     }
 
     func setupNotification() {
@@ -182,111 +179,122 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
         }
     }
 
-    @MainActor private func configureState() async {
+    private func configureState() async {
         let glucoseValuesIDs = await fetchGlucose()
-        guard let lastDeterminationID = await fetchlastDetermination().first,
-              let latestOverrideID = await fetchLatestOverride() else { return }
+        async let lastDeterminationIDs = fetchlastDetermination()
+        async let latestOverrideID = fetchLatestOverride()
+
+        guard let lastDeterminationID = await lastDeterminationIDs.first,
+              let latestOverrideID = await latestOverrideID
+        else {
+            debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to get last Determination/ last Override")
+            return
+        }
 
         do {
-            let glucoseValues = try glucoseValuesIDs.compactMap { id in
-                try viewContext.existingObject(with: id) as? GlucoseStored
-            }
+            let glucoseValues: [GlucoseStored] = await CoreDataStack.shared
+                .getNSManagedObject(with: glucoseValuesIDs, context: viewContext)
 
             let lastDetermination = try viewContext.existingObject(with: lastDeterminationID) as? OrefDetermination
             let latestOverride = try viewContext.existingObject(with: latestOverrideID) as? OverrideStored
 
-            if let firstGlucoseValue = glucoseValues.first {
-                let value = settingsManager.settings
-                    .units == .mgdL ? Decimal(firstGlucoseValue.glucose) : Decimal(firstGlucoseValue.glucose).asMmolL
-                state.glucose = glucoseFormatter.string(from: value as NSNumber)
-                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
-                state.delta = deltaFormatter.string(from: deltaConverted as NSNumber)
-                state.trendRaw = firstGlucoseValue.direction
-                state.glucoseDate = firstGlucoseValue.date
-            }
-
-            state.lastLoopDate = lastDetermination?.timestamp
-            state.lastLoopDateInterval = state.lastLoopDate.map {
-                guard $0.timeIntervalSince1970 > 0 else { return 0 }
-                return UInt64($0.timeIntervalSince1970)
-            }
-            state.bolusIncrement = settingsManager.preferences.bolusIncrement
-            state.maxCOB = settingsManager.preferences.maxCOB
-            state.maxBolus = settingsManager.pumpSettings.maxBolus
-            state.carbsRequired = lastDetermination?.carbsRequired as? Decimal
-
-            var insulinRequired = lastDetermination?.insulinReq as? Decimal ?? 0
-
-            var double: Decimal = 2
-            if lastDetermination?.manualBolusErrorString == 0 {
-                insulinRequired = lastDetermination?.insulinForManualBolus as? Decimal ?? 0
-                double = 1
-            }
-
-            state.useNewCalc = settingsManager.settings.useCalc
+            let recommendedInsulin = await newBolusCalc(
+                ids: glucoseValuesIDs,
+                determination: lastDetermination
+            )
+
+            await MainActor.run { [weak self] in
+                guard let self = self else { return }
+
+                if let firstGlucoseValue = glucoseValues.first {
+                    let value = self.settingsManager.settings.units == .mgdL
+                        ? Decimal(firstGlucoseValue.glucose)
+                        : Decimal(firstGlucoseValue.glucose).asMmolL
+
+                    self.state.glucose = self.glucoseFormatter.string(from: value as NSNumber)
+                    self.state.trend = firstGlucoseValue.directionEnum?.symbol
+
+                    let delta = glucoseValues.count >= 2
+                        ? Decimal(firstGlucoseValue.glucose) - Decimal(glucoseValues.dropFirst().first?.glucose ?? 0)
+                        : 0
+                    let deltaConverted = self.settingsManager.settings.units == .mgdL ? delta : delta.asMmolL
+                    self.state.delta = self.deltaFormatter.string(from: deltaConverted as NSNumber)
+                    self.state.trendRaw = firstGlucoseValue.direction
+                    self.state.glucoseDate = firstGlucoseValue.date
+                }
 
-            if !(state.useNewCalc ?? false) {
-                state.bolusRecommended = apsManager
-                    .roundBolus(amount: max(
-                        insulinRequired * (settingsManager.settings.insulinReqPercentage / 100) * double,
-                        0
-                    ))
-            } else {
-                let recommended = await newBolusCalc(
-                    ids: glucoseValuesIDs,
-                    determination: lastDetermination
-                )
-                state.bolusRecommended = apsManager
-                    .roundBolus(amount: max(recommended, 0))
-            }
-            state.bolusAfterCarbs = !settingsManager.settings.skipBolusScreenAfterCarbs
-            state.displayOnWatch = settingsManager.settings.displayOnWatch
-            state.displayFatAndProteinOnWatch = settingsManager.settings.displayFatAndProteinOnWatch
-            state.confirmBolusFaster = settingsManager.settings.confirmBolusFaster
-
-            state.iob = lastDetermination?.iob as? Decimal
-            state.cob = lastDetermination?.cob as? Decimal
-            state.tempTargets = tempTargetsStorage.presets()
-                .map { target -> TempTargetWatchPreset in
-                    let untilDate = self.tempTargetsStorage.current().flatMap { currentTarget -> Date? in
-                        guard currentTarget.id == target.id else { return nil }
-                        let date = currentTarget.createdAt.addingTimeInterval(TimeInterval(currentTarget.duration * 60))
-                        return date > Date() ? date : nil
+                self.state.lastLoopDate = lastDetermination?.timestamp
+                self.state.lastLoopDateInterval = self.state.lastLoopDate.map {
+                    guard $0.timeIntervalSince1970 > 0 else { return 0 }
+                    return UInt64($0.timeIntervalSince1970)
+                }
+                self.state.bolusIncrement = self.settingsManager.preferences.bolusIncrement
+                self.state.maxCOB = self.settingsManager.preferences.maxCOB
+                self.state.maxBolus = self.settingsManager.pumpSettings.maxBolus
+                self.state.carbsRequired = lastDetermination?.carbsRequired as? Decimal
+
+//                var insulinRequired = lastDetermination?.insulinReq as? Decimal ?? 0
+//
+//                var double: Decimal = 2
+//                if lastDetermination?.manualBolusErrorString == 0 {
+//                    insulinRequired = lastDetermination?.insulinForManualBolus as? Decimal ?? 0
+//                    double = 1
+//                }
+
+                self.state.useNewCalc = self.settingsManager.settings.useCalc
+                self.state.bolusRecommended = self.apsManager
+                    .roundBolus(amount: max(recommendedInsulin, 0))
+                self.state.bolusAfterCarbs = !self.settingsManager.settings.skipBolusScreenAfterCarbs
+                self.state.displayOnWatch = self.settingsManager.settings.displayOnWatch
+                self.state.displayFatAndProteinOnWatch = self.settingsManager.settings.displayFatAndProteinOnWatch
+                self.state.confirmBolusFaster = self.settingsManager.settings.confirmBolusFaster
+
+                self.state.iob = lastDetermination?.iob as? Decimal
+                if let cobValue = lastDetermination?.cob {
+                    self.state.cob = Decimal(cobValue)
+                } else {
+                    self.state.cob = 0
+                }
+                self.state.tempTargets = self.tempTargetsStorage.presets()
+                    .map { target -> TempTargetWatchPreset in
+                        let untilDate = self.tempTargetsStorage.current().flatMap { currentTarget -> Date? in
+                            guard currentTarget.id == target.id else { return nil }
+                            let date = currentTarget.createdAt.addingTimeInterval(TimeInterval(currentTarget.duration * 60))
+                            return date > Date() ? date : nil
+                        }
+                        return TempTargetWatchPreset(
+                            name: target.displayName,
+                            id: target.id,
+                            description: self.descriptionForTarget(target),
+                            until: untilDate
+                        )
                     }
-                    return TempTargetWatchPreset(
-                        name: target.displayName,
-                        id: target.id,
-                        description: self.descriptionForTarget(target),
-                        until: untilDate
-                    )
+                self.state.bolusAfterCarbs = !self.settingsManager.settings.skipBolusScreenAfterCarbs
+                self.state.displayOnWatch = self.settingsManager.settings.displayOnWatch
+                self.state.displayFatAndProteinOnWatch = self.settingsManager.settings.displayFatAndProteinOnWatch
+                self.state.confirmBolusFaster = self.settingsManager.settings.confirmBolusFaster
+
+                if let eventualBG = self.settingsManager.settings.units == .mgdL ? lastDetermination?
+                    .eventualBG : lastDetermination?
+                    .eventualBG?.decimalValue.asMmolL as NSDecimalNumber?
+                {
+                    let eventualBGAsString = self.eventualFormatter.string(from: eventualBG)
+                    self.state.eventualBG = eventualBGAsString.map { "⇢ " + $0 }
+                    self.state.eventualBGRaw = eventualBGAsString
                 }
-            state.bolusAfterCarbs = !settingsManager.settings.skipBolusScreenAfterCarbs
-            state.displayOnWatch = settingsManager.settings.displayOnWatch
-            state.displayFatAndProteinOnWatch = settingsManager.settings.displayFatAndProteinOnWatch
-            state.confirmBolusFaster = settingsManager.settings.confirmBolusFaster
-
-            if let eventualBG = settingsManager.settings.units == .mgdL ? lastDetermination?.eventualBG : lastDetermination?
-                .eventualBG?.decimalValue.asMmolL as NSDecimalNumber?
-            {
-                let eventualBGAsString = eventualFormatter.string(from: eventualBG)
-                state.eventualBG = eventualBGAsString.map { "⇢ " + $0 }
-                state.eventualBGRaw = eventualBGAsString
-            }
 
-            state.isf = lastDetermination?.insulinSensitivity as? Decimal
+                self.state.isf = lastDetermination?.insulinSensitivity as? Decimal
 
-            if latestOverride?.enabled ?? false {
-                let percentString = "\((latestOverride?.percentage ?? 100).formatted(.number)) %"
-                state.override = percentString
+                if latestOverride?.enabled ?? false {
+                    let percentString = "\((latestOverride?.percentage ?? 100).formatted(.number)) %"
+                    self.state.override = percentString
 
-            } else {
-                state.override = "100 %"
-            }
+                } else {
+                    self.state.override = "100 %"
+                }
 
-            sendState()
+                self.sendState()
+            }
 
         } catch let error as NSError {
             debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to configure state with error: \(error)")