Kaynağa Gözat

ns manager rework to use CD entites

polscm32 2 yıl önce
ebeveyn
işleme
1bd28666e9

+ 2 - 2
FreeAPS/Sources/Models/NightscoutStatus.swift

@@ -9,8 +9,8 @@ struct NightscoutStatus: JSON {
 
 struct OpenAPSStatus: JSON {
     let iob: IOBEntry?
-    let suggested: Suggestion?
-    let enacted: Suggestion?
+    let suggested: Determination?
+    let enacted: Determination?
     let version: String
 }
 

+ 0 - 2
FreeAPS/Sources/Modules/Home/HomeDataFlow.swift

@@ -6,8 +6,6 @@ enum Home {
 }
 
 protocol HomeProvider: Provider {
-    var suggestion: Suggestion? { get }
-    var enactedSuggestion: Suggestion? { get }
     func heartbeatNow()
     func pumpHistory(hours: Int) -> [PumpHistoryEvent]
     func pumpSettings() -> PumpSettings

+ 0 - 8
FreeAPS/Sources/Modules/Home/HomeProvider.swift

@@ -11,14 +11,6 @@ extension Home {
         @Injected() var carbsStorage: CarbsStorage!
         @Injected() var announcementStorage: AnnouncementsStorage!
 
-        var suggestion: Suggestion? {
-            storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
-        }
-
-        var enactedSuggestion: Suggestion? {
-            storage.retrieve(OpenAPS.Enact.enacted, as: Suggestion.self)
-        }
-
         func pumpTimeZone() -> TimeZone? {
             apsManager.pumpManager?.status.timeZone
         }

+ 1 - 1
FreeAPS/Sources/Modules/NightscoutConfig/NightscoutConfigStateModel.swift

@@ -17,7 +17,7 @@ extension NightscoutConfig {
         @Injected() var apsManager: APSManager!
 
         let coredataContext = CoreDataStack.shared.backgroundContext
-        
+
         @Published var url = ""
         @Published var secret = ""
         @Published var message = ""

+ 0 - 2
FreeAPS/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -134,8 +134,6 @@ extension Settings {
                                 .navigationLink(to: .configEditor(file: OpenAPS.Settings.profile), from: self)
                             Text("Carbs")
                                 .navigationLink(to: .configEditor(file: OpenAPS.Monitor.carbHistory), from: self)
-                            Text("Enacted")
-                                .navigationLink(to: .configEditor(file: OpenAPS.Enact.enacted), from: self)
                             Text("Announcements")
                                 .navigationLink(to: .configEditor(file: OpenAPS.FreeAPS.announcements), from: self)
                             Text("Enacted announcements")

+ 203 - 7
FreeAPS/Sources/Services/Network/NightscoutManager.swift

@@ -1,4 +1,5 @@
 import Combine
+import CoreData
 import Foundation
 import LoopKitUI
 import Swinject
@@ -63,6 +64,8 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
     private let context = CoreDataStack.shared.backgroundContext
 
+    private var lastTwoDeterminations: [OrefDetermination]?
+
     init(resolver: Resolver) {
         injectServices(resolver)
         subscribe()
@@ -409,15 +412,209 @@ 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
+        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"
+            )
+        }
+    }
+
     func uploadStatus() {
         let iob = storage.retrieve(OpenAPS.Monitor.iob, as: [IOBEntry].self)
-        var suggested = storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
-        var enacted = storage.retrieve(OpenAPS.Enact.enacted, as: Suggestion.self)
 
-        if (suggested?.timestamp ?? .distantPast) > (enacted?.timestamp ?? .distantPast) {
-            enacted?.predictions = nil
-        } else {
-            suggested?.predictions = nil
+        let penultimateDetermination = lastTwoDeterminations?.last
+        let lastDetermination = lastTwoDeterminations?.first
+
+        var suggested: Determination?
+        var enacted: Determination?
+
+        if let lastDetermination = lastDetermination, let penultimateDetermination = penultimateDetermination {
+            if lastDetermination.enacted, penultimateDetermination.enacted {
+                suggested = Determination(
+                    reason: lastDetermination.reason ?? "",
+                    units: lastDetermination.smbToDeliver?.decimalValue,
+                    insulinReq: lastDetermination.insulinReq?.decimalValue,
+                    eventualBG: Int(truncating: lastDetermination.eventualBG ?? 0),
+                    sensitivityRatio: lastDetermination.sensitivityRatio?.decimalValue,
+                    rate: lastDetermination.rate?.decimalValue,
+                    duration: Int(lastDetermination.duration),
+                    iob: lastDetermination.iob?.decimalValue,
+                    cob: Decimal(lastDetermination.cob),
+                    predictions: nil,
+                    deliverAt: lastDetermination.deliverAt ?? Date(),
+                    carbsReq: Decimal(lastDetermination.carbsRequired),
+                    temp: TempType(rawValue: lastDetermination.temp ?? ""),
+                    bg: lastDetermination.glucose?.decimalValue,
+                    reservoir: lastDetermination.reservoir?.decimalValue,
+                    isf: lastDetermination.insulinSensitivity?.decimalValue,
+                    timestamp: lastDetermination.timestamp,
+                    recieved: lastDetermination.received,
+                    tdd: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                    insulin: Insulin(
+                        TDD: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                        bolus: lastDetermination.bolus?.decimalValue ?? Decimal(0),
+                        temp_basal: lastDetermination.tempBasal?.decimalValue ?? Decimal(0),
+                        scheduled_basal: lastDetermination.scheduledBasal?.decimalValue ?? Decimal(0)
+                    ),
+                    current_target: lastDetermination.currentTarget?.decimalValue ?? Decimal(0),
+                    insulinForManualBolus: lastDetermination.insulinForManualBolus?.decimalValue ?? Decimal(0),
+                    manualBolusErrorString: lastDetermination.manualBolusErrorString?.decimalValue ?? Decimal(0),
+                    minDelta: lastDetermination.minDelta?.decimalValue ?? Decimal(0),
+                    expectedDelta: lastDetermination.expectedDelta?.decimalValue ?? Decimal(0),
+                    minGuardBG: nil, minPredBG: nil, threshold: lastDetermination.treshold?.decimalValue ?? Decimal(0),
+                    carbRatio: lastDetermination.carbRatio?.decimalValue ?? Decimal(0)
+                )
+                enacted = Determination(
+                    reason: lastDetermination.reason ?? "",
+                    units: lastDetermination.smbToDeliver?.decimalValue,
+                    insulinReq: lastDetermination.insulinReq?.decimalValue,
+                    eventualBG: Int(truncating: lastDetermination.eventualBG ?? 0),
+                    sensitivityRatio: lastDetermination.sensitivityRatio?.decimalValue,
+                    rate: lastDetermination.rate?.decimalValue,
+                    duration: Int(lastDetermination.duration),
+                    iob: lastDetermination.iob?.decimalValue,
+                    cob: Decimal(lastDetermination.cob),
+                    predictions: nil,
+                    deliverAt: lastDetermination.deliverAt ?? Date(),
+                    carbsReq: Decimal(lastDetermination.carbsRequired),
+                    temp: TempType(rawValue: lastDetermination.temp ?? ""),
+                    bg: lastDetermination.glucose?.decimalValue,
+                    reservoir: lastDetermination.reservoir?.decimalValue,
+                    isf: lastDetermination.insulinSensitivity?.decimalValue,
+                    timestamp: lastDetermination.timestamp,
+                    recieved: lastDetermination.received,
+                    tdd: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                    insulin: Insulin(
+                        TDD: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                        bolus: lastDetermination.bolus?.decimalValue ?? Decimal(0),
+                        temp_basal: lastDetermination.tempBasal?.decimalValue ?? Decimal(0),
+                        scheduled_basal: lastDetermination.scheduledBasal?.decimalValue ?? Decimal(0)
+                    ),
+                    current_target: lastDetermination.currentTarget?.decimalValue ?? Decimal(0),
+                    insulinForManualBolus: lastDetermination.insulinForManualBolus?.decimalValue ?? Decimal(0),
+                    manualBolusErrorString: lastDetermination.manualBolusErrorString?.decimalValue ?? Decimal(0),
+                    minDelta: lastDetermination.minDelta?.decimalValue ?? Decimal(0),
+                    expectedDelta: lastDetermination.expectedDelta?.decimalValue ?? Decimal(0),
+                    minGuardBG: nil, minPredBG: nil, threshold: lastDetermination.treshold?.decimalValue ?? Decimal(0),
+                    carbRatio: lastDetermination.carbRatio?.decimalValue ?? Decimal(0)
+                )
+            }  else if !lastDetermination.enacted, penultimateDetermination.enacted {
+                suggested = Determination(
+                    reason: lastDetermination.reason ?? "",
+                    units: lastDetermination.smbToDeliver?.decimalValue,
+                    insulinReq: lastDetermination.insulinReq?.decimalValue,
+                    eventualBG: Int(truncating: lastDetermination.eventualBG ?? 0),
+                    sensitivityRatio: lastDetermination.sensitivityRatio?.decimalValue,
+                    rate: lastDetermination.rate?.decimalValue,
+                    duration: Int(lastDetermination.duration),
+                    iob: lastDetermination.iob?.decimalValue,
+                    cob: Decimal(lastDetermination.cob),
+                    predictions: nil,
+                    deliverAt: lastDetermination.deliverAt ?? Date(),
+                    carbsReq: Decimal(lastDetermination.carbsRequired),
+                    temp: TempType(rawValue: lastDetermination.temp ?? ""),
+                    bg: lastDetermination.glucose?.decimalValue,
+                    reservoir: lastDetermination.reservoir?.decimalValue,
+                    isf: lastDetermination.insulinSensitivity?.decimalValue,
+                    timestamp: lastDetermination.timestamp,
+                    recieved: lastDetermination.received,
+                    tdd: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                    insulin: Insulin(
+                        TDD: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                        bolus: lastDetermination.bolus?.decimalValue ?? Decimal(0),
+                        temp_basal: lastDetermination.tempBasal?.decimalValue ?? Decimal(0),
+                        scheduled_basal: lastDetermination.scheduledBasal?.decimalValue ?? Decimal(0)
+                    ),
+                    current_target: lastDetermination.currentTarget?.decimalValue ?? Decimal(0),
+                    insulinForManualBolus: lastDetermination.insulinForManualBolus?.decimalValue ?? Decimal(0),
+                    manualBolusErrorString: lastDetermination.manualBolusErrorString?.decimalValue ?? Decimal(0),
+                    minDelta: lastDetermination.minDelta?.decimalValue ?? Decimal(0),
+                    expectedDelta: lastDetermination.expectedDelta?.decimalValue ?? Decimal(0),
+                    minGuardBG: nil, minPredBG: nil, threshold: lastDetermination.treshold?.decimalValue ?? Decimal(0),
+                    carbRatio: lastDetermination.carbRatio?.decimalValue ?? Decimal(0)
+                )
+                enacted = Determination(
+                    reason: penultimateDetermination.reason ?? "",
+                    units: penultimateDetermination.smbToDeliver?.decimalValue,
+                    insulinReq: penultimateDetermination.insulinReq?.decimalValue,
+                    eventualBG: Int(truncating: penultimateDetermination.eventualBG ?? 0),
+                    sensitivityRatio: penultimateDetermination.sensitivityRatio?.decimalValue,
+                    rate: penultimateDetermination.rate?.decimalValue,
+                    duration: Int(penultimateDetermination.duration),
+                    iob: penultimateDetermination.iob?.decimalValue,
+                    cob: Decimal(penultimateDetermination.cob),
+                    predictions: nil,
+                    deliverAt: penultimateDetermination.deliverAt ?? Date(),
+                    carbsReq: Decimal(penultimateDetermination.carbsRequired),
+                    temp: TempType(rawValue: penultimateDetermination.temp ?? ""),
+                    bg: penultimateDetermination.glucose?.decimalValue,
+                    reservoir: penultimateDetermination.reservoir?.decimalValue,
+                    isf: penultimateDetermination.insulinSensitivity?.decimalValue,
+                    timestamp: penultimateDetermination.timestamp,
+                    recieved: penultimateDetermination.received,
+                    tdd: penultimateDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                    insulin: Insulin(
+                        TDD: penultimateDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                        bolus: penultimateDetermination.bolus?.decimalValue ?? Decimal(0),
+                        temp_basal: penultimateDetermination.tempBasal?.decimalValue ?? Decimal(0),
+                        scheduled_basal: penultimateDetermination.scheduledBasal?.decimalValue ?? Decimal(0)
+                    ),
+                    current_target: penultimateDetermination.currentTarget?.decimalValue ?? Decimal(0),
+                    insulinForManualBolus: penultimateDetermination.insulinForManualBolus?.decimalValue ?? Decimal(0),
+                    manualBolusErrorString: penultimateDetermination.manualBolusErrorString?.decimalValue ?? Decimal(0),
+                    minDelta: penultimateDetermination.minDelta?.decimalValue ?? Decimal(0),
+                    expectedDelta: penultimateDetermination.expectedDelta?.decimalValue ?? Decimal(0),
+                    minGuardBG: nil,
+                    minPredBG: nil,
+                    threshold: penultimateDetermination.treshold?.decimalValue ?? Decimal(0),
+                    carbRatio: penultimateDetermination.carbRatio?.decimalValue ?? Decimal(0)
+                )
+            } else if !lastDetermination.enacted, !penultimateDetermination.enacted {
+                suggested = Determination(
+                    reason: lastDetermination.reason ?? "",
+                    units: lastDetermination.smbToDeliver?.decimalValue,
+                    insulinReq: lastDetermination.insulinReq?.decimalValue,
+                    eventualBG: Int(truncating: lastDetermination.eventualBG ?? 0),
+                    sensitivityRatio: lastDetermination.sensitivityRatio?.decimalValue,
+                    rate: lastDetermination.rate?.decimalValue,
+                    duration: Int(lastDetermination.duration),
+                    iob: lastDetermination.iob?.decimalValue,
+                    cob: Decimal(lastDetermination.cob),
+                    predictions: nil,
+                    deliverAt: lastDetermination.deliverAt ?? Date(),
+                    carbsReq: Decimal(lastDetermination.carbsRequired),
+                    temp: TempType(rawValue: lastDetermination.temp ?? ""),
+                    bg: lastDetermination.glucose?.decimalValue,
+                    reservoir: lastDetermination.reservoir?.decimalValue,
+                    isf: lastDetermination.insulinSensitivity?.decimalValue,
+                    timestamp: lastDetermination.timestamp,
+                    recieved: lastDetermination.received,
+                    tdd: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                    insulin: Insulin(
+                        TDD: lastDetermination.totalDailyDose?.decimalValue ?? Decimal(0),
+                        bolus: lastDetermination.bolus?.decimalValue ?? Decimal(0),
+                        temp_basal: lastDetermination.tempBasal?.decimalValue ?? Decimal(0),
+                        scheduled_basal: lastDetermination.scheduledBasal?.decimalValue ?? Decimal(0)
+                    ),
+                    current_target: lastDetermination.currentTarget?.decimalValue ?? Decimal(0),
+                    insulinForManualBolus: lastDetermination.insulinForManualBolus?.decimalValue ?? Decimal(0),
+                    manualBolusErrorString: lastDetermination.manualBolusErrorString?.decimalValue ?? Decimal(0),
+                    minDelta: lastDetermination.minDelta?.decimalValue ?? Decimal(0),
+                    expectedDelta: lastDetermination.expectedDelta?.decimalValue ?? Decimal(0),
+                    minGuardBG: nil, minPredBG: nil, threshold: lastDetermination.treshold?.decimalValue ?? Decimal(0),
+                    carbRatio: lastDetermination.carbRatio?.decimalValue ?? Decimal(0)
+                )
+            }
         }
 
         let loopIsClosed = settingsManager.settings.closedLoop
@@ -442,7 +639,6 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
 
         let battery = fetchBattery()
-//        let battery = storage.retrieve(OpenAPS.Monitor.battery, as: Battery.self)
 
         var reservoir = Decimal(from: storage.retrieveRaw(OpenAPS.Monitor.reservoir) ?? "0")
         if reservoir == 0xDEAD_BEEF {

+ 14 - 18
FreeAPS/Sources/Services/WatchManager/WatchManager.swift

@@ -33,14 +33,12 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
         }
 
         broadcaster.register(GlucoseObserver.self, observer: self)
-        broadcaster.register(SuggestionObserver.self, observer: self)
         broadcaster.register(SettingsObserver.self, observer: self)
         broadcaster.register(PumpHistoryObserver.self, observer: self)
         broadcaster.register(PumpSettingsObserver.self, observer: self)
         broadcaster.register(BasalProfileObserver.self, observer: self)
         broadcaster.register(TempTargetsObserver.self, observer: self)
         broadcaster.register(CarbsObserver.self, observer: self)
-        broadcaster.register(EnactedSuggestionObserver.self, observer: self)
         broadcaster.register(PumpBatteryObserver.self, observer: self)
         broadcaster.register(PumpReservoirObserver.self, observer: self)
         garmin.stateRequet = { [weak self] () -> Data in
@@ -65,17 +63,29 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
         }
     }
 
+    private func fetchDetermination() -> [OrefDetermination] {
+        do {
+            let results = try context.fetch(OrefDetermination.fetch(NSPredicate.enactedDetermination))
+            debugPrint("Watch Manager: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) fetched determinations")
+            return results
+        } catch {
+            debugPrint("Watch Manager: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to fetch determinations")
+            return []
+        }
+    }
+
     private func configureState() {
         processQueue.async {
             let fetchedReadings = self.fetchGlucose()
             let glucoseValues = self.glucoseText(fetchedReadings)
+            let fetchedDeterminations = self.fetchDetermination()
+
             self.state.glucose = glucoseValues.glucose
             self.state.trend = glucoseValues.trend
             self.state.delta = glucoseValues.delta
             self.state.trendRaw = fetchedReadings.first?.direction ?? "↔︎"
             self.state.glucoseDate = fetchedReadings.first?.date ?? .distantPast
-            self.state.lastLoopDate = self.enactedSuggestion?.recieved == true ? self.enactedSuggestion?.deliverAt : self
-                .apsManager.lastLoopDate
+            self.state.lastLoopDate = fetchedDeterminations.first?.deliverAt
             self.state.lastLoopDateInterval = self.state.lastLoopDate.map {
                 guard $0.timeIntervalSince1970 > 0 else { return 0 }
                 return UInt64($0.timeIntervalSince1970)
@@ -308,10 +318,6 @@ final class BaseWatchManager: NSObject, WatchManager, Injectable {
     private var suggestion: Suggestion? {
         storage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
     }
-
-    private var enactedSuggestion: Suggestion? {
-        storage.retrieve(OpenAPS.Enact.enacted, as: Suggestion.self)
-    }
 }
 
 extension BaseWatchManager: WCSessionDelegate {
@@ -412,14 +418,12 @@ extension BaseWatchManager: WCSessionDelegate {
 
 extension BaseWatchManager:
     GlucoseObserver,
-    SuggestionObserver,
     SettingsObserver,
     PumpHistoryObserver,
     PumpSettingsObserver,
     BasalProfileObserver,
     TempTargetsObserver,
     CarbsObserver,
-    EnactedSuggestionObserver,
     PumpBatteryObserver,
     PumpReservoirObserver
 {
@@ -427,10 +431,6 @@ extension BaseWatchManager:
         configureState()
     }
 
-    func suggestionDidUpdate(_: Suggestion) {
-        configureState()
-    }
-
     func settingsDidChange(_: FreeAPSSettings) {
         configureState()
     }
@@ -455,10 +455,6 @@ extension BaseWatchManager:
         // TODO:
     }
 
-    func enactedSuggestionDidUpdate(_: Suggestion) {
-        configureState()
-    }
-
     func pumpBatteryDidChange(_: Battery) {
         // TODO:
     }

+ 11 - 11
FreeAPS/Sources/Shortcuts/State/StateIntentRequest.swift

@@ -55,27 +55,27 @@ enum StateIntentError: Error {
 
 @available(iOS 16.0, *) final class StateIntentRequest: BaseIntentsRequest {
     let moc = CoreDataStack.shared.backgroundContext
-    
-    func getLastGlucose() throws -> (dateGlucose: Date, glucose: String, trend: String, delta: String)  {
+
+    func getLastGlucose() throws -> (dateGlucose: Date, glucose: String, trend: String, delta: String) {
         do {
-           let results = try moc.fetch(GlucoseStored.fetch(NSPredicate.predicateFor30MinAgo, ascending: false, fetchLimit: 2))
+            let results = try moc.fetch(GlucoseStored.fetch(NSPredicate.predicateFor30MinAgo, ascending: false, fetchLimit: 2))
             debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.succeeded) fetched latest glucose")
-            
+
             guard let lastValue = results.first else { throw StateIntentError.NoBG }
-            
-            ///calculate delta
+
+            /// calculate delta
             let lastGlucose = lastValue.glucose
             let secondLastGlucose = results.dropFirst().first?.glucose
             let delta = results.count > 1 ? (lastGlucose - (secondLastGlucose ?? 0)) : nil
-            ///formatting
+            /// formatting
             let units = settingsManager.settings.units
             let glucoseAsString = glucoseFormatter.string(from: Double(
                 units == .mmolL ? Decimal(lastGlucose)
                     .asMmolL : Decimal(lastGlucose)
             ) as NSNumber)!
-            
+
             let directionAsString = lastValue.direction ?? "none"
-            
+
             let deltaAsString = delta
                 .map {
                     self.deltaFormatter
@@ -91,14 +91,14 @@ enum StateIntentError: Error {
             return (Date(), "", "", "")
         }
     }
-    
+
     func getIobAndCob() throws -> (iob: Double, cob: Double) {
         do {
             let results = try moc.fetch(OrefDetermination.fetch(NSPredicate.enactedDetermination))
             let iobAsDouble = Double(truncating: (results.first?.iob ?? 0.0) as NSNumber)
             let cobAsDouble = Double(truncating: (results.first?.cob ?? 0) as NSNumber)
             debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.succeeded) fetched latest cob and iob")
-            
+
             return (iobAsDouble, cobAsDouble)
         } catch {
             debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.failed) failed to fetch latest cob and iob")