diff --git a/FreeAPS/Sources/APS/APSManager.swift b/FreeAPS/Sources/APS/APSManager.swift index 87be59e6b..dca7d4a86 100644 --- a/FreeAPS/Sources/APS/APSManager.swift +++ b/FreeAPS/Sources/APS/APSManager.swift @@ -735,7 +735,7 @@ final class BaseAPSManager: APSManager, Injectable { } // parse to determination -// let det = Determination(reason: enacted.reason, units: enacted.smbToDeliver, insulinReq: enacted.insulinReq, eventualBG: enacted.eventualBG, sensitivityRatio: enacted.sensitivityRatio, rate: enacted.rate, duration: enacted.duration, iob: enacted.iob, cob: enacted.cob, deliverAt: enacted.deliverAt, carbsReq: enacted.carbsRequired, temp: enacted.temp, bg: enacted.glucose, reservoir: enacted.reservoir, isf: enacted.insulinSensitivity, tdd: enacted.totalDailyDose, current_target: enacted.currentTarget, insulinForManualBolus: enacted.insulinForManualBolus, manualBolusErrorString: enacted.manualBolusErrorString, minDelta: enacted.minDelta, expectedDelta: enacted.expectedDelta, threshold: enacted.treshold, carbRatio: enacted.carbRatio) +// let det = Determination(reason: enacted.reason, units: enacted.smbToDeliver, insulinReq: enacted.insulinReq, eventualBG: enacted.eventualBG, sensitivityRatio: enacted.sensitivityRatio, rate: enacted.rate, duration: enacted.duration, iob: enacted.iob, cob: enacted.cob, deliverAt: enacted.deliverAt, carbsReq: enacted.carbsRequired, temp: enacted.temp, bg: enacted.glucose, reservoir: enacted.reservoir, isf: enacted.insulinSensitivity, tdd: enacted.totalDailyDose, current_target: enacted.currentTarget, insulinForManualBolus: enacted.insulinForManualBolus, manualBolusErrorString: enacted.manualBolusErrorString, minDelta: enacted.minDelta, expectedDelta: enacted.expectedDelta, threshold: enacted.threshold, carbRatio: enacted.carbRatio) let saveLastLoop = LastLoop(context: self.privateContext) saveLastLoop.iob = (determination.iob ?? 0) as NSDecimalNumber diff --git a/FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift b/FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift index de160b80e..796a2fb36 100644 --- a/FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift +++ b/FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift @@ -15,6 +15,83 @@ final class OpenAPS { self.storage = storage } + // Helper function to convert a Decimal? to NSDecimalNumber? + func decimalToNSDecimalNumber(_ value: Decimal?) -> NSDecimalNumber? { + guard let value = value else { return nil } + return NSDecimalNumber(decimal: value) + } + + // Use the helper function for cleaner code + func processDetermination(_ determination: Determination) { + context.perform { + let newOrefDetermination = OrefDetermination(context: self.context) + newOrefDetermination.id = UUID() + + newOrefDetermination.totalDailyDose = self.decimalToNSDecimalNumber(determination.tdd) + newOrefDetermination.insulinSensitivity = self.decimalToNSDecimalNumber(determination.isf) + newOrefDetermination.currentTarget = self.decimalToNSDecimalNumber(determination.current_target) + newOrefDetermination.eventualBG = determination.eventualBG.map(NSDecimalNumber.init) + newOrefDetermination.deliverAt = determination.deliverAt + newOrefDetermination.insulinForManualBolus = self.decimalToNSDecimalNumber(determination.insulinForManualBolus) + newOrefDetermination.carbRatio = self.decimalToNSDecimalNumber(determination.carbRatio) + newOrefDetermination.glucose = self.decimalToNSDecimalNumber(determination.bg) + newOrefDetermination.reservoir = self.decimalToNSDecimalNumber(determination.reservoir) + newOrefDetermination.insulinReq = self.decimalToNSDecimalNumber(determination.insulinReq) + newOrefDetermination.temp = determination.temp?.rawValue ?? "absolute" + newOrefDetermination.rate = self.decimalToNSDecimalNumber(determination.rate) + newOrefDetermination.reason = determination.reason + newOrefDetermination.duration = Int16(determination.duration ?? 0) + newOrefDetermination.iob = self.decimalToNSDecimalNumber(determination.iob) + newOrefDetermination.threshold = self.decimalToNSDecimalNumber(determination.threshold) + newOrefDetermination.minDelta = self.decimalToNSDecimalNumber(determination.minDelta) + newOrefDetermination.sensitivityRatio = self.decimalToNSDecimalNumber(determination.sensitivityRatio) + newOrefDetermination.expectedDelta = self.decimalToNSDecimalNumber(determination.expectedDelta) + newOrefDetermination.cob = Int16(Int(determination.cob ?? 0)) + newOrefDetermination.manualBolusErrorString = self.decimalToNSDecimalNumber(determination.manualBolusErrorString) + newOrefDetermination.tempBasal = determination.insulin?.temp_basal.map { NSDecimalNumber(decimal: $0) } + newOrefDetermination.scheduledBasal = determination.insulin?.scheduled_basal.map { NSDecimalNumber(decimal: $0) } + newOrefDetermination.bolus = determination.insulin?.bolus.map { NSDecimalNumber(decimal: $0) } + newOrefDetermination.smbToDeliver = determination.units.map { NSDecimalNumber(decimal: $0) } + newOrefDetermination.carbsRequired = Int16(Int(determination.carbsReq ?? 0)) + + if let predictions = determination.predictions { + ["iob": predictions.iob, "zt": predictions.zt, "cob": predictions.cob, "uam": predictions.uam] + .forEach { type, values in + if let values = values { + let forecast = Forecast(context: self.context) + forecast.id = UUID() + forecast.type = type + forecast.date = Date() + forecast.orefDetermination = newOrefDetermination + + for (index, value) in values.enumerated() { + let forecastValue = ForecastValue(context: self.context) + forecastValue.index = Int32(index) + forecastValue.value = Int32(value) + forecast.addToForecastValues(forecastValue) + } + newOrefDetermination.addToForecasts(forecast) + } + } + } + + self.attemptToSaveContext() + } + } + + func attemptToSaveContext() { + if context.hasChanges { + do { + try context.save() + debugPrint("OpenAPS: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved determination") + } catch { + debugPrint( + "OpenAPS: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) error while saving determination: \(error.localizedDescription)" + ) + } + } + } + func determineBasal(currentTemp: TempBasal, clock: Date = Date()) -> Future { Future { promise in self.processQueue.async { @@ -82,79 +159,9 @@ final class OpenAPS { if var determination = Determination(from: orefDetermination) { determination.timestamp = determination.deliverAt ?? clock self.storage.save(determination, as: Enact.suggested) - // save to core data asynchronously - self.context.perform { - let newOrefDetermination = OrefDetermination(context: self.context) - newOrefDetermination.id = UUID() - newOrefDetermination.totalDailyDose = determination.tdd as? NSDecimalNumber - newOrefDetermination.insulinSensitivity = determination.isf as? NSDecimalNumber - newOrefDetermination.currentTarget = determination.current_target as? NSDecimalNumber - newOrefDetermination.eventualBG = determination.eventualBG as? NSDecimalNumber - newOrefDetermination.deliverAt = determination.deliverAt - newOrefDetermination.enacted = false - newOrefDetermination.insulinForManualBolus = determination.insulinForManualBolus as? NSDecimalNumber - newOrefDetermination.carbRatio = determination.carbRatio as? NSDecimalNumber - newOrefDetermination.glucose = determination.bg as? NSDecimalNumber - newOrefDetermination.reservoir = determination.reservoir as? NSDecimalNumber - newOrefDetermination.insulinReq = determination.insulinReq as? NSDecimalNumber - newOrefDetermination.temp = determination.temp?.rawValue ?? "absolute" - newOrefDetermination.rate = determination.rate as? NSDecimalNumber - newOrefDetermination.reason = determination.reason - newOrefDetermination.duration = Int16(determination.duration ?? 0) - newOrefDetermination.iob = determination.iob as? NSDecimalNumber - newOrefDetermination.treshold = determination.treshold as? NSDecimalNumber - - if let predictions = determination.predictions { - // Create forecasts for each type - ["iob": predictions.iob, "zt": predictions.zt, "cob": predictions.cob, "uam": predictions.uam] - .forEach { type, values in - if let values = values { - let forecast = Forecast(context: self.context) - forecast.id = UUID() - forecast.type = type - forecast.date = Date() // or use a specific timestamp if available - forecast - .orefDetermination = - newOrefDetermination // Assuming a relationship from Forecast to OrefDetermination - - for (index, value) in values.enumerated() { - let forecastValue = ForecastValue(context: self.context) - forecastValue.index = Int32(index) - forecastValue.value = Int32(value) - forecast.addToForecastValues(forecastValue) - } - newOrefDetermination.addToForecasts(forecast) - } - } - } - - newOrefDetermination.minDelta = determination.minDelta as? NSDecimalNumber - newOrefDetermination.sensitivityRatio = determination.sensitivityRatio as? NSDecimalNumber - newOrefDetermination.expectedDelta = determination.expectedDelta as? NSDecimalNumber - newOrefDetermination.cob = Int16(Int(determination.cob ?? 0)) - newOrefDetermination.manualBolusErrorString = determination.manualBolusErrorString as? NSDecimalNumber - newOrefDetermination.timestampEnacted = nil - newOrefDetermination.tempBasal = determination.insulin?.temp_basal as? NSDecimalNumber - newOrefDetermination.scheduledBasal = determination.insulin?.scheduled_basal as? NSDecimalNumber - newOrefDetermination.bolus = determination.insulin?.bolus as? NSDecimalNumber - newOrefDetermination.smbToDeliver = determination.units as? NSDecimalNumber - newOrefDetermination.carbsRequired = Int16(Int(determination.carbsReq ?? 0)) - - if self.context.hasChanges { - do { - try self.context.save() - debugPrint( - "OpenAPS: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved determination" - ) - } catch { - debugPrint( - "OpenAPS: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) error while saving determination" - ) - } - } - } - // MARK: Save to CoreData also. To do: Remove JSON saving + // save to core data asynchronously + self.processDetermination(determination) if determination.tdd ?? 0 > 0 { self.context.perform { diff --git a/FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift b/FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift index 667e5cfa0..2c7c7c5a3 100644 --- a/FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift +++ b/FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift @@ -237,7 +237,7 @@ extension MainChartView { drawGlucose() drawManualGlucose() - /// high and low treshold lines + /// high and low threshold lines if thresholdLines { RuleMark(y: .value("High", highGlucose * conversionFactor)).foregroundStyle(Color.loopYellow) .lineStyle(.init(lineWidth: 1, dash: [5])) diff --git a/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift b/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift index 10a995b5c..d49b70717 100644 --- a/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift +++ b/FreeAPS/Sources/Modules/Home/View/HomeRootView.swift @@ -461,6 +461,13 @@ extension Home { ) .font(.system(size: 16)) } + } else { + HStack { + Image(systemName: "arrow.right.circle") + .font(.system(size: 16, weight: .bold)) + Text("--") + .font(.system(size: 16)) + } } // if let eventualBG = state.eventualBG { // HStack { diff --git a/Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents b/Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents index 414cfafaa..79f349a5c 100644 --- a/Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents +++ b/Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents @@ -130,10 +130,10 @@ + - diff --git a/OrefDetermination+CoreDataProperties.swift b/OrefDetermination+CoreDataProperties.swift index baad66415..603006f05 100644 --- a/OrefDetermination+CoreDataProperties.swift +++ b/OrefDetermination+CoreDataProperties.swift @@ -36,7 +36,7 @@ public extension OrefDetermination { @NSManaged var timestamp: Date? @NSManaged var timestampEnacted: Date? @NSManaged var totalDailyDose: NSDecimalNumber? - @NSManaged var treshold: NSDecimalNumber? + @NSManaged var threshold: NSDecimalNumber? @NSManaged var forecasts: Set? }