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

Merge branch 'core-data' of github.com:polscm32/Open-iAPS into core-data

dnzxy 2 лет назад
Родитель
Сommit
294b1a08c5

+ 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
 }
 

+ 1 - 1
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -97,7 +97,7 @@ extension Bolus {
 
         let now = Date.now
 
-        let context = CoreDataStack.shared.backgroundContext
+        let context = CoreDataStack.shared.viewContext
 
         override func subscribe() {
             fetchGlucose()

+ 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
         }

+ 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.threshold?.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.threshold?.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.threshold?.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.threshold?.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.threshold?.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:
     }

+ 2 - 2
FreeAPS/Sources/Shortcuts/State/ListStateIntent.swift

@@ -17,8 +17,8 @@ import Foundation
     }
 
     @MainActor func perform() async throws -> some ReturnsValue<StateiAPSResults> & ShowsSnippetView {
-        let glucoseValues = try? stateIntent.getLastBG()
-        let iob_cob_value = try? stateIntent.getIOB_COB()
+        let glucoseValues = try? stateIntent.getLastGlucose()
+        let iob_cob_value = try? stateIntent.getIobAndCob()
 
         guard let glucoseValue = glucoseValues else { throw StateIntentError.NoBG }
         guard let iob_cob = iob_cob_value else { throw StateIntentError.NoIOBCOB }

+ 46 - 30
FreeAPS/Sources/Shortcuts/State/StateIntentRequest.swift

@@ -54,40 +54,56 @@ enum StateIntentError: Error {
 }
 
 @available(iOS 16.0, *) final class StateIntentRequest: BaseIntentsRequest {
-    func getLastBG() throws -> (dateGlucose: Date, glucose: String, trend: String, delta: String) {
-        let glucose = glucoseStorage.recent()
-        guard let lastGlucose = glucose.last, let glucoseValue = lastGlucose.glucose else { throw StateIntentError.NoBG }
-        let delta = glucose.count >= 2 ? glucoseValue - (glucose[glucose.count - 2].glucose ?? 0) : nil
-        let units = settingsManager.settings.units
-
-        let glucoseText = glucoseFormatter
-            .string(from: Double(
-                units == .mmolL ? glucoseValue
-                    .asMmolL : Decimal(glucoseValue)
+    let moc = CoreDataStack.shared.backgroundContext
+
+    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))
+            debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.succeeded) fetched latest glucose")
+
+            guard let lastValue = results.first else { throw StateIntentError.NoBG }
+
+            /// calculate delta
+            let lastGlucose = lastValue.glucose
+            let secondLastGlucose = results.dropFirst().first?.glucose
+            let delta = results.count > 1 ? (lastGlucose - (secondLastGlucose ?? 0)) : nil
+            /// formatting
+            let units = settingsManager.settings.units
+            let glucoseAsString = glucoseFormatter.string(from: Double(
+                units == .mmolL ? Decimal(lastGlucose)
+                    .asMmolL : Decimal(lastGlucose)
             ) as NSNumber)!
-        let directionText = lastGlucose.direction?.rawValue ?? "none"
-        let deltaText = delta
-            .map {
-                self.deltaFormatter
-                    .string(from: Double(
-                        units == .mmolL ? $0
-                            .asMmolL : Decimal($0)
-                    ) as NSNumber)!
-            } ?? "--"
-
-        return (lastGlucose.dateString, glucoseText, directionText, deltaText)
-    }
 
-    func getIOB_COB() throws -> (iob: Double, cob: Double) {
-        let iob = suggestion?.iob ?? 0.0
-        let cob = suggestion?.cob ?? 0.0
-        let iob_double = Double(truncating: iob as NSNumber)
-        let cob_double = Double(truncating: cob as NSNumber)
-        return (iob_double, cob_double)
+            let directionAsString = lastValue.direction ?? "none"
+
+            let deltaAsString = delta
+                .map {
+                    self.deltaFormatter
+                        .string(from: Double(
+                            units == .mmolL ? Decimal($0)
+                                .asMmolL : Decimal($0)
+                        ) as NSNumber)!
+                } ?? "--"
+            debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.succeeded) fetched latest 2 glucose values")
+            return (lastValue.date ?? Date(), glucoseAsString, directionAsString, deltaAsString)
+        } catch {
+            debugPrint("StateIntentRequest: \(#function) \(DebuggingIdentifiers.failed) failed to fetch latest 2 glucose values")
+            return (Date(), "", "", "")
+        }
     }
 
-    private var suggestion: Suggestion? {
-        fileStorage.retrieve(OpenAPS.Enact.suggested, as: Suggestion.self)
+    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")
+            return (0.0, 0.0)
+        }
     }
 
     private var glucoseFormatter: NumberFormatter {