Parcourir la source

Refactoring WiP...

polscm32 il y a 1 an
Parent
commit
af255f1f32

+ 24 - 16
FreeAPS.xcodeproj/project.pbxproj

@@ -259,6 +259,12 @@
 		5864E8592C42CFAE00294306 /* DeterminationStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5864E8582C42CFAE00294306 /* DeterminationStorage.swift */; };
 		587DA1F62B77F3DD00B28F8A /* SettingsRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */; };
 		5887527C2BD986E1008B081D /* OpenAPSBattery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5887527B2BD986E1008B081D /* OpenAPSBattery.swift */; };
+		58A3D53A2C96D4DE003F90FC /* AddTempTargetForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D5392C96D4DE003F90FC /* AddTempTargetForm.swift */; };
+		58A3D5442C96DE11003F90FC /* TempTargetStored+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D5432C96DE11003F90FC /* TempTargetStored+Helper.swift */; };
+		58A3D5512C96EFA8003F90FC /* TempTargetStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D54D2C96EFA8003F90FC /* TempTargetStored+CoreDataClass.swift */; };
+		58A3D5522C96EFA8003F90FC /* TempTargetStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D54E2C96EFA8003F90FC /* TempTargetStored+CoreDataProperties.swift */; };
+		58A3D5532C96EFA8003F90FC /* TempTargetRunStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D54F2C96EFA8003F90FC /* TempTargetRunStored+CoreDataClass.swift */; };
+		58A3D5542C96EFA8003F90FC /* TempTargetRunStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A3D5502C96EFA8003F90FC /* TempTargetRunStored+CoreDataProperties.swift */; };
 		58D08B222C8DAA8E00AA37D3 /* OverrideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D08B212C8DAA8E00AA37D3 /* OverrideView.swift */; };
 		58D08B302C8DEA7500AA37D3 /* ForecastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D08B2F2C8DEA7500AA37D3 /* ForecastView.swift */; };
 		58D08B322C8DF88900AA37D3 /* DummyCharts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D08B312C8DF88900AA37D3 /* DummyCharts.swift */; };
@@ -457,8 +463,6 @@
 		DDE179592C910127003CDDB7 /* ForecastValue+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179392C910127003CDDB7 /* ForecastValue+CoreDataProperties.swift */; };
 		DDE1795A2C910127003CDDB7 /* CarbEntryStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793A2C910127003CDDB7 /* CarbEntryStored+CoreDataClass.swift */; };
 		DDE1795B2C910127003CDDB7 /* CarbEntryStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793B2C910127003CDDB7 /* CarbEntryStored+CoreDataProperties.swift */; };
-		DDE1795C2C910127003CDDB7 /* TempTargets+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793C2C910127003CDDB7 /* TempTargets+CoreDataClass.swift */; };
-		DDE1795D2C910127003CDDB7 /* TempTargets+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793D2C910127003CDDB7 /* TempTargets+CoreDataProperties.swift */; };
 		DDE1795E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift */; };
 		DDE1795F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1793F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift */; };
 		DDE179602C910127003CDDB7 /* StatsData+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179402C910127003CDDB7 /* StatsData+CoreDataClass.swift */; };
@@ -471,8 +475,6 @@
 		DDE179672C910127003CDDB7 /* OpenAPS_Battery+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179472C910127003CDDB7 /* OpenAPS_Battery+CoreDataProperties.swift */; };
 		DDE179682C910127003CDDB7 /* TempBasalStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179482C910127003CDDB7 /* TempBasalStored+CoreDataClass.swift */; };
 		DDE179692C910127003CDDB7 /* TempBasalStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE179492C910127003CDDB7 /* TempBasalStored+CoreDataProperties.swift */; };
-		DDE1796A2C910127003CDDB7 /* TempTargetsSlider+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1794A2C910127003CDDB7 /* TempTargetsSlider+CoreDataClass.swift */; };
-		DDE1796B2C910127003CDDB7 /* TempTargetsSlider+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1794B2C910127003CDDB7 /* TempTargetsSlider+CoreDataProperties.swift */; };
 		DDE1796C2C910127003CDDB7 /* OverrideRunStored+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1794C2C910127003CDDB7 /* OverrideRunStored+CoreDataClass.swift */; };
 		DDE1796D2C910127003CDDB7 /* OverrideRunStored+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1794D2C910127003CDDB7 /* OverrideRunStored+CoreDataProperties.swift */; };
 		DDE1796E2C910127003CDDB7 /* OrefDetermination+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE1794E2C910127003CDDB7 /* OrefDetermination+CoreDataClass.swift */; };
@@ -910,6 +912,12 @@
 		5864E8582C42CFAE00294306 /* DeterminationStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeterminationStorage.swift; sourceTree = "<group>"; };
 		587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRowView.swift; sourceTree = "<group>"; };
 		5887527B2BD986E1008B081D /* OpenAPSBattery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenAPSBattery.swift; sourceTree = "<group>"; };
+		58A3D5392C96D4DE003F90FC /* AddTempTargetForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTempTargetForm.swift; sourceTree = "<group>"; };
+		58A3D5432C96DE11003F90FC /* TempTargetStored+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetStored+Helper.swift"; sourceTree = "<group>"; };
+		58A3D54D2C96EFA8003F90FC /* TempTargetStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetStored+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
+		58A3D54E2C96EFA8003F90FC /* TempTargetStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetStored+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
+		58A3D54F2C96EFA8003F90FC /* TempTargetRunStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetRunStored+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
+		58A3D5502C96EFA8003F90FC /* TempTargetRunStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetRunStored+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
 		58D08B212C8DAA8E00AA37D3 /* OverrideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverrideView.swift; sourceTree = "<group>"; };
 		58D08B2F2C8DEA7500AA37D3 /* ForecastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastView.swift; sourceTree = "<group>"; };
 		58D08B312C8DF88900AA37D3 /* DummyCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyCharts.swift; sourceTree = "<group>"; };
@@ -1111,8 +1119,6 @@
 		DDE179392C910127003CDDB7 /* ForecastValue+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ForecastValue+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE1793A2C910127003CDDB7 /* CarbEntryStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarbEntryStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		DDE1793B2C910127003CDDB7 /* CarbEntryStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarbEntryStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
-		DDE1793C2C910127003CDDB7 /* TempTargets+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargets+CoreDataClass.swift"; sourceTree = "<group>"; };
-		DDE1793D2C910127003CDDB7 /* TempTargets+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargets+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE1793E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpEventStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		DDE1793F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpEventStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE179402C910127003CDDB7 /* StatsData+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatsData+CoreDataClass.swift"; sourceTree = "<group>"; };
@@ -1125,8 +1131,6 @@
 		DDE179472C910127003CDDB7 /* OpenAPS_Battery+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenAPS_Battery+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE179482C910127003CDDB7 /* TempBasalStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempBasalStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		DDE179492C910127003CDDB7 /* TempBasalStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempBasalStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
-		DDE1794A2C910127003CDDB7 /* TempTargetsSlider+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetsSlider+CoreDataClass.swift"; sourceTree = "<group>"; };
-		DDE1794B2C910127003CDDB7 /* TempTargetsSlider+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TempTargetsSlider+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE1794C2C910127003CDDB7 /* OverrideRunStored+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OverrideRunStored+CoreDataClass.swift"; sourceTree = "<group>"; };
 		DDE1794D2C910127003CDDB7 /* OverrideRunStored+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OverrideRunStored+CoreDataProperties.swift"; sourceTree = "<group>"; };
 		DDE1794E2C910127003CDDB7 /* OrefDetermination+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrefDetermination+CoreDataClass.swift"; sourceTree = "<group>"; };
@@ -2240,6 +2244,7 @@
 				BDF34EBD2C0A31D000D51995 /* CustomNotification.swift */,
 				BDCD47AE2C1F3F1700F8BCD5 /* OverrideStored+helper.swift */,
 				BDB899892C565D0B006F3298 /* CarbsGlucose+helper.swift */,
+				58A3D5432C96DE11003F90FC /* TempTargetStored+Helper.swift */,
 			);
 			path = Helper;
 			sourceTree = "<group>";
@@ -2671,6 +2676,7 @@
 				DDD163172C4C694000CD525A /* OverrideRootView.swift */,
 				DDD163192C4C695E00CD525A /* EditOverrideForm.swift */,
 				DDD1631B2C4C697400CD525A /* AddOverrideForm.swift */,
+				58A3D5392C96D4DE003F90FC /* AddTempTargetForm.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -2678,6 +2684,10 @@
 		DDE179112C9100FA003CDDB7 /* Classes+Properties */ = {
 			isa = PBXGroup;
 			children = (
+				58A3D54D2C96EFA8003F90FC /* TempTargetStored+CoreDataClass.swift */,
+				58A3D54E2C96EFA8003F90FC /* TempTargetStored+CoreDataProperties.swift */,
+				58A3D54F2C96EFA8003F90FC /* TempTargetRunStored+CoreDataClass.swift */,
+				58A3D5502C96EFA8003F90FC /* TempTargetRunStored+CoreDataProperties.swift */,
 				DDE179322C910127003CDDB7 /* MealPresetStored+CoreDataClass.swift */,
 				DDE179332C910127003CDDB7 /* MealPresetStored+CoreDataProperties.swift */,
 				DDE179342C910127003CDDB7 /* LoopStatRecord+CoreDataClass.swift */,
@@ -2688,8 +2698,6 @@
 				DDE179392C910127003CDDB7 /* ForecastValue+CoreDataProperties.swift */,
 				DDE1793A2C910127003CDDB7 /* CarbEntryStored+CoreDataClass.swift */,
 				DDE1793B2C910127003CDDB7 /* CarbEntryStored+CoreDataProperties.swift */,
-				DDE1793C2C910127003CDDB7 /* TempTargets+CoreDataClass.swift */,
-				DDE1793D2C910127003CDDB7 /* TempTargets+CoreDataProperties.swift */,
 				DDE1793E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift */,
 				DDE1793F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift */,
 				DDE179402C910127003CDDB7 /* StatsData+CoreDataClass.swift */,
@@ -2702,8 +2710,6 @@
 				DDE179472C910127003CDDB7 /* OpenAPS_Battery+CoreDataProperties.swift */,
 				DDE179482C910127003CDDB7 /* TempBasalStored+CoreDataClass.swift */,
 				DDE179492C910127003CDDB7 /* TempBasalStored+CoreDataProperties.swift */,
-				DDE1794A2C910127003CDDB7 /* TempTargetsSlider+CoreDataClass.swift */,
-				DDE1794B2C910127003CDDB7 /* TempTargetsSlider+CoreDataProperties.swift */,
 				DDE1794C2C910127003CDDB7 /* OverrideRunStored+CoreDataClass.swift */,
 				DDE1794D2C910127003CDDB7 /* OverrideRunStored+CoreDataProperties.swift */,
 				DDE1794E2C910127003CDDB7 /* OrefDetermination+CoreDataClass.swift */,
@@ -3158,6 +3164,7 @@
 				CE7CA3552A064973004BE681 /* ListStateIntent.swift in Sources */,
 				BDF530D82B40F8AC002CAF43 /* LockScreenView.swift in Sources */,
 				195D80B72AF697B800D25097 /* DynamicSettingsDataFlow.swift in Sources */,
+				58A3D5512C96EFA8003F90FC /* TempTargetStored+CoreDataClass.swift in Sources */,
 				3862CC2E2743F9F700BF832C /* CalendarManager.swift in Sources */,
 				CEA4F62329BE10F70011ADF7 /* SavitzkyGolayFilter.swift in Sources */,
 				38B4F3C325E2A20B00E76A18 /* PumpSetupView.swift in Sources */,
@@ -3199,6 +3206,7 @@
 				DD1745552C55CA6C00211FAC /* UnitsLimitsSettingsRootView.swift in Sources */,
 				384E803825C388640086DB71 /* Script.swift in Sources */,
 				CE94597E29E9E1EE0047C9C6 /* GarminManager.swift in Sources */,
+				58A3D5542C96EFA8003F90FC /* TempTargetRunStored+CoreDataProperties.swift in Sources */,
 				3883583425EEB38000E024B2 /* PumpSettings.swift in Sources */,
 				38DAB280260CBB7F00F74C1A /* PumpView.swift in Sources */,
 				DDD1631C2C4C697400CD525A /* AddOverrideForm.swift in Sources */,
@@ -3235,6 +3243,7 @@
 				5837A5302BD2E3C700A5DC04 /* CarbEntryStored+helper.swift in Sources */,
 				389A572026079BAA00BC102F /* Interpolation.swift in Sources */,
 				19A910382A24EF3200C8951B /* ChartsView.swift in Sources */,
+				58A3D5522C96EFA8003F90FC /* TempTargetStored+CoreDataProperties.swift in Sources */,
 				BDF34F832C10C5B600D51995 /* DataManager.swift in Sources */,
 				38B4F3C625E5017E00E76A18 /* NotificationCenter.swift in Sources */,
 				19D466A729AA2C22004D5F33 /* MealSettingsStateModel.swift in Sources */,
@@ -3275,6 +3284,7 @@
 				58D08B222C8DAA8E00AA37D3 /* OverrideView.swift in Sources */,
 				BD0B2EF32C5998E600B3298F /* MealPresetView.swift in Sources */,
 				582DF9752C8CDB92001F516D /* GlucoseChartView.swift in Sources */,
+				58A3D53A2C96D4DE003F90FC /* AddTempTargetForm.swift in Sources */,
 				DD1745302C55AE5300211FAC /* TargetBehaviorProvider.swift in Sources */,
 				58D08B382C8DFB6000AA37D3 /* BasalChart.swift in Sources */,
 				118DF76D2C5ECBC60067FEB7 /* OverridePresetEntity.swift in Sources */,
@@ -3458,6 +3468,8 @@
 				58D08B3A2C8DFECD00AA37D3 /* TempTargets.swift in Sources */,
 				38E98A2325F52C9300C0CED0 /* Signpost.swift in Sources */,
 				CE7CA3542A064973004BE681 /* TempPresetsIntentRequest.swift in Sources */,
+				58A3D5442C96DE11003F90FC /* TempTargetStored+Helper.swift in Sources */,
+				58A3D5532C96EFA8003F90FC /* TempTargetRunStored+CoreDataClass.swift in Sources */,
 				DD6B7CB42C7B71F700B75029 /* ForecastDisplayType.swift in Sources */,
 				F5F7E6C1B7F098F59EB67EC5 /* TargetsEditorDataFlow.swift in Sources */,
 				DD17453A2C55BFA600211FAC /* AlgorithmAdvancedSettingsDataFlow.swift in Sources */,
@@ -3553,8 +3565,6 @@
 				DDE179592C910127003CDDB7 /* ForecastValue+CoreDataProperties.swift in Sources */,
 				DDE1795A2C910127003CDDB7 /* CarbEntryStored+CoreDataClass.swift in Sources */,
 				DDE1795B2C910127003CDDB7 /* CarbEntryStored+CoreDataProperties.swift in Sources */,
-				DDE1795C2C910127003CDDB7 /* TempTargets+CoreDataClass.swift in Sources */,
-				DDE1795D2C910127003CDDB7 /* TempTargets+CoreDataProperties.swift in Sources */,
 				DDE1795E2C910127003CDDB7 /* PumpEventStored+CoreDataClass.swift in Sources */,
 				DDE1795F2C910127003CDDB7 /* PumpEventStored+CoreDataProperties.swift in Sources */,
 				DDE179602C910127003CDDB7 /* StatsData+CoreDataClass.swift in Sources */,
@@ -3567,8 +3577,6 @@
 				DDE179672C910127003CDDB7 /* OpenAPS_Battery+CoreDataProperties.swift in Sources */,
 				DDE179682C910127003CDDB7 /* TempBasalStored+CoreDataClass.swift in Sources */,
 				DDE179692C910127003CDDB7 /* TempBasalStored+CoreDataProperties.swift in Sources */,
-				DDE1796A2C910127003CDDB7 /* TempTargetsSlider+CoreDataClass.swift in Sources */,
-				DDE1796B2C910127003CDDB7 /* TempTargetsSlider+CoreDataProperties.swift in Sources */,
 				DDE1796C2C910127003CDDB7 /* OverrideRunStored+CoreDataClass.swift in Sources */,
 				DDE1796D2C910127003CDDB7 /* OverrideRunStored+CoreDataProperties.swift in Sources */,
 				DDE1796E2C910127003CDDB7 /* OrefDetermination+CoreDataClass.swift in Sources */,

+ 219 - 43
FreeAPS/Sources/APS/OpenAPS/OpenAPS.swift

@@ -411,13 +411,6 @@ final class OpenAPS {
                 debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch TDD Data")
             }
 
-            var sliderArray = [TempTargetsSlider]()
-            let requestIsEnbled = TempTargetsSlider.fetchRequest() as NSFetchRequest<TempTargetsSlider>
-            let sortIsEnabled = NSSortDescriptor(key: "date", ascending: false)
-            requestIsEnbled.sortDescriptors = [sortIsEnabled]
-            // requestIsEnbled.fetchLimit = 1
-            try? sliderArray = self.context.fetch(requestIsEnbled)
-
             /// Get the last active Override as only this information is apparently used in oref2
             var overrideArray = [OverrideStored]()
             let requestOverrides = OverrideStored.fetchRequest() as NSFetchRequest<OverrideStored>
@@ -427,8 +420,8 @@ final class OpenAPS {
             requestOverrides.fetchLimit = 1
             try? overrideArray = self.context.fetch(requestOverrides)
 
-            var tempTargetsArray = [TempTargets]()
-            let requestTempTargets = TempTargets.fetchRequest() as NSFetchRequest<TempTargets>
+            var tempTargetsArray = [TempTargetStored]()
+            let requestTempTargets = TempTargetStored.fetchRequest() as NSFetchRequest<TempTargetStored>
             let sortTT = NSSortDescriptor(key: "date", ascending: false)
             requestTempTargets.sortDescriptors = [sortTT]
             requestTempTargets.fetchLimit = 1
@@ -436,14 +429,14 @@ final class OpenAPS {
 
             let total = uniqueEvents.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 }).reduce(0, +)
             var indeces = uniqueEvents.count
-            // Only fetch once. Use same (previous) fetch
+
+            // Fetch data for two hours
             let twoHoursArray = uniqueEvents.filter({ ($0["timestamp"] as? Date ?? Date()) >= twoHoursAgo })
             var nrOfIndeces = twoHoursArray.count
             let totalAmount = twoHoursArray.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 })
                 .reduce(0, +)
 
-            var temptargetActive = tempTargetsArray.first?.active ?? false
-            let isPercentageEnabled = sliderArray.first?.enabled ?? false
+            var isTemptargetActive = tempTargetsArray.first?.enabled ?? false
 
             var useOverride = overrideArray.first?.enabled ?? false
             var overridePercentage = Decimal(overrideArray.first?.percentage ?? 100)
@@ -452,18 +445,13 @@ final class OpenAPS {
 
             let currentTDD = (uniqueEvents.last?["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0
 
-            if indeces == 0 {
-                indeces = 1
-            }
-            if nrOfIndeces == 0 {
-                nrOfIndeces = 1
-            }
+            if indeces == 0 { indeces = 1 }
+            if nrOfIndeces == 0 { nrOfIndeces = 1 }
 
             let average2hours = totalAmount / Decimal(nrOfIndeces)
             let average14 = total / Decimal(indeces)
 
-            let weight = wp
-            let weighted_average = weight * average2hours + (1 - weight) * average14
+            let weightedAverage = wp * average2hours + (1 - wp) * average14
 
             var duration: Decimal = 0
             var overrideTarget: Decimal = 0
@@ -474,9 +462,7 @@ final class OpenAPS {
                 let advancedSettings = overrideArray.first?.advancedSettings ?? false
                 let addedMinutes = Int(duration)
                 let date = overrideArray.first?.date ?? Date()
-                if date.addingTimeInterval(addedMinutes.minutes.timeInterval) < Date(),
-                   !unlimited
-                {
+                if date.addingTimeInterval(addedMinutes.minutes.timeInterval) < Date(), !unlimited {
                     useOverride = false
                     let saveToCoreData = OverrideStored(context: self.context)
                     saveToCoreData.enabled = false
@@ -501,35 +487,33 @@ final class OpenAPS {
                 disableSMBs = false
             }
 
-            if temptargetActive {
+            if isTemptargetActive {
                 var duration_ = 0
                 var hbt = Double(hbt_)
                 var dd = 0.0
 
-                if temptargetActive {
-                    duration_ = Int(truncating: tempTargetsArray.first?.duration ?? 0)
-                    hbt = tempTargetsArray.first?.hbt ?? Double(hbt_)
-                    let startDate = tempTargetsArray.first?.startDate ?? Date()
-                    let durationPlusStart = startDate.addingTimeInterval(duration_.minutes.timeInterval)
-                    dd = durationPlusStart.timeIntervalSinceNow.minutes
-
-                    if dd > 0.1 {
-                        hbt_ = Decimal(hbt)
-                        temptargetActive = true
-                    } else {
-                        temptargetActive = false
-                    }
+                duration_ = Int(truncating: tempTargetsArray.first?.duration ?? 0)
+                hbt = Double(truncating: tempTargetsArray.first?.target ?? NSDecimalNumber(value: Double(hbt_)))
+                let startDate = tempTargetsArray.first?.date ?? Date()
+                let durationPlusStart = startDate.addingTimeInterval(duration_.minutes.timeInterval)
+                dd = durationPlusStart.timeIntervalSinceNow.minutes
+
+                if dd > 0.1 {
+                    hbt_ = Decimal(hbt)
+                    isTemptargetActive = true
+                } else {
+                    isTemptargetActive = false
                 }
             }
 
             if currentTDD > 0 {
                 let averages = Oref2_variables(
                     average_total_data: average14,
-                    weightedAverage: weighted_average,
+                    weightedAverage: weightedAverage,
                     past2hoursAverage: average2hours,
                     date: Date(),
-                    isEnabled: temptargetActive,
-                    presetActive: isPercentageEnabled,
+                    isEnabled: isTemptargetActive,
+                    presetActive: isTemptargetActive,
                     overridePercentage: overridePercentage,
                     useOverride: useOverride,
                     duration: duration,
@@ -546,7 +530,6 @@ final class OpenAPS {
                 )
 
                 self.storage.save(averages, as: OpenAPS.Monitor.oref2_variables)
-
                 return self.loadFileFromStorage(name: Monitor.oref2_variables)
 
             } else {
@@ -555,8 +538,8 @@ final class OpenAPS {
                     weightedAverage: 1,
                     past2hoursAverage: 0,
                     date: Date(),
-                    isEnabled: temptargetActive,
-                    presetActive: isPercentageEnabled,
+                    isEnabled: isTemptargetActive,
+                    presetActive: isTemptargetActive,
                     overridePercentage: overridePercentage,
                     useOverride: useOverride,
                     duration: duration,
@@ -577,6 +560,199 @@ final class OpenAPS {
         }
     }
 
+//    func oref2() async -> RawJSON {
+//        await context.perform {
+//            let preferences = self.storage.retrieve(OpenAPS.Settings.preferences, as: Preferences.self)
+//            var hbt_ = preferences?.halfBasalExerciseTarget ?? 160
+//            let wp = preferences?.weightPercentage ?? 1
+//            let smbMinutes = (preferences?.maxSMBBasalMinutes ?? 30) as NSDecimalNumber
+//            let uamMinutes = (preferences?.maxUAMSMBBasalMinutes ?? 30) as NSDecimalNumber
+//
+//            let tenDaysAgo = Date().addingTimeInterval(-10.days.timeInterval)
+//            let twoHoursAgo = Date().addingTimeInterval(-2.hours.timeInterval)
+//
+//            var uniqueEvents = [[String: Any]]()
+//            let requestTDD = OrefDetermination.fetchRequest() as NSFetchRequest<NSFetchRequestResult>
+//            requestTDD.predicate = NSPredicate(format: "timestamp > %@ AND totalDailyDose > 0", tenDaysAgo as NSDate)
+//            requestTDD.propertiesToFetch = ["timestamp", "totalDailyDose"]
+//            let sortTDD = NSSortDescriptor(key: "timestamp", ascending: true)
+//            requestTDD.sortDescriptors = [sortTDD]
+//            requestTDD.resultType = .dictionaryResultType
+//
+//            do {
+//                if let fetchedResults = try self.context.fetch(requestTDD) as? [[String: Any]] {
+//                    uniqueEvents = fetchedResults
+//                }
+//            } catch {
+//                debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to fetch TDD Data")
+//            }
+//
+    ////            var sliderArray = [TempTargetStored]()
+    ////            let requestIsEnbled = TempTargetStored.fetchRequest() as NSFetchRequest<TempTargetStored>
+    ////            let sortIsEnabled = NSSortDescriptor(key: "date", ascending: false)
+    ////            requestIsEnbled.sortDescriptors = [sortIsEnabled]
+    ////            // requestIsEnbled.fetchLimit = 1
+    ////            try? sliderArray = self.context.fetch(requestIsEnbled)
+//
+//            /// Get the last active Override as only this information is apparently used in oref2
+//            var overrideArray = [OverrideStored]()
+//            let requestOverrides = OverrideStored.fetchRequest() as NSFetchRequest<OverrideStored>
+//            let sortOverride = NSSortDescriptor(key: "date", ascending: false)
+//            requestOverrides.sortDescriptors = [sortOverride]
+//            requestOverrides.predicate = NSPredicate.lastActiveOverride
+//            requestOverrides.fetchLimit = 1
+//            try? overrideArray = self.context.fetch(requestOverrides)
+//
+//            var tempTargetsArray = [TempTargetStored]()
+//            let requestTempTargets = TempTargetStored.fetchRequest() as NSFetchRequest<TempTargetStored>
+//            let sortTT = NSSortDescriptor(key: "date", ascending: false)
+//            requestTempTargets.sortDescriptors = [sortTT]
+//            requestTempTargets.fetchLimit = 1
+//            try? tempTargetsArray = self.context.fetch(requestTempTargets)
+//
+//            let total = uniqueEvents.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 }).reduce(0, +)
+//            var indeces = uniqueEvents.count
+//            // Only fetch once. Use same (previous) fetch
+//            let twoHoursArray = uniqueEvents.filter({ ($0["timestamp"] as? Date ?? Date()) >= twoHoursAgo })
+//            var nrOfIndeces = twoHoursArray.count
+//            let totalAmount = twoHoursArray.compactMap({ ($0["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0 })
+//                .reduce(0, +)
+//
+//            var isTemptargetActive = tempTargetsArray.first?.enabled ?? false
+//
+//            var useOverride = overrideArray.first?.enabled ?? false
+//            var overridePercentage = Decimal(overrideArray.first?.percentage ?? 100)
+//            var unlimited = overrideArray.first?.indefinite ?? true
+//            var disableSMBs = overrideArray.first?.smbIsOff ?? false
+//
+//            let currentTDD = (uniqueEvents.last?["totalDailyDose"] as? NSDecimalNumber)?.decimalValue ?? 0
+//
+//            if indeces == 0 {
+//                indeces = 1
+//            }
+//            if nrOfIndeces == 0 {
+//                nrOfIndeces = 1
+//            }
+//
+//            let average2hours = totalAmount / Decimal(nrOfIndeces)
+//            let average14 = total / Decimal(indeces)
+//
+//            let weight = wp
+//            let weighted_average = weight * average2hours + (1 - weight) * average14
+//
+//            var duration: Decimal = 0
+//            var overrideTarget: Decimal = 0
+//
+//            if useOverride {
+//                duration = (overrideArray.first?.duration ?? 0) as Decimal
+//                overrideTarget = (overrideArray.first?.target ?? 0) as Decimal
+//                let advancedSettings = overrideArray.first?.advancedSettings ?? false
+//                let addedMinutes = Int(duration)
+//                let date = overrideArray.first?.date ?? Date()
+//                if date.addingTimeInterval(addedMinutes.minutes.timeInterval) < Date(),
+//                   !unlimited
+//                {
+//                    useOverride = false
+//                    let saveToCoreData = OverrideStored(context: self.context)
+//                    saveToCoreData.enabled = false
+//                    saveToCoreData.date = Date()
+//                    saveToCoreData.duration = 0
+//                    saveToCoreData.indefinite = false
+//                    saveToCoreData.percentage = 100
+//                    do {
+//                        guard self.context.hasChanges else { return "{}" }
+//                        try self.context.save()
+//                    } catch {
+//                        print(error.localizedDescription)
+//                    }
+//                }
+//            }
+//
+//            if !useOverride {
+//                unlimited = true
+//                overridePercentage = 100
+//                duration = 0
+//                overrideTarget = 0
+//                disableSMBs = false
+//            }
+//
+//            if isTemptargetActive {
+//                var duration_ = 0
+//                var hbt = Double(hbt_)
+//                var dd = 0.0
+//
+//                duration_ = Int(truncating: tempTargetsArray.first?.duration ?? 0)
+//                hbt = tempTargetsArray.first?.target ?? Double(hbt_)
+//                let startDate = tempTargetsArray.first?.startDate ?? Date()
+//                let durationPlusStart = startDate.addingTimeInterval(duration_.minutes.timeInterval)
+//                dd = durationPlusStart.timeIntervalSinceNow.minutes
+//
+//                if dd > 0.1 {
+//                    hbt_ = Decimal(hbt)
+//                    isTemptargetActive = true
+//                } else {
+//                    isTemptargetActive = false
+//                }
+//
+//            }
+//
+//            // TODO: - adapt oref2 struct to remove double use of isTemptargetActive
+//
+//            if currentTDD > 0 {
+//                let averages = Oref2_variables(
+//                    average_total_data: average14,
+//                    weightedAverage: weighted_average,
+//                    past2hoursAverage: average2hours,
+//                    date: Date(),
+//                    isEnabled: isTemptargetActive,
+//                    presetActive: isTemptargetActive,
+//                    overridePercentage: overridePercentage,
+//                    useOverride: useOverride,
+//                    duration: duration,
+//                    unlimited: unlimited,
+//                    hbt: hbt_,
+//                    overrideTarget: overrideTarget,
+//                    smbIsOff: disableSMBs,
+//                    advancedSettings: overrideArray.first?.advancedSettings ?? false,
+//                    isfAndCr: overrideArray.first?.isfAndCr ?? false,
+//                    isf: overrideArray.first?.isf ?? false,
+//                    cr: overrideArray.first?.cr ?? false,
+//                    smbMinutes: (overrideArray.first?.smbMinutes ?? smbMinutes) as Decimal,
+//                    uamMinutes: (overrideArray.first?.uamMinutes ?? uamMinutes) as Decimal
+//                )
+//
+//                self.storage.save(averages, as: OpenAPS.Monitor.oref2_variables)
+//
+//                return self.loadFileFromStorage(name: Monitor.oref2_variables)
+//
+//            } else {
+//                let averages = Oref2_variables(
+//                    average_total_data: 0,
+//                    weightedAverage: 1,
+//                    past2hoursAverage: 0,
+//                    date: Date(),
+//                    isEnabled: isTemptargetActive,
+//                    presetActive: isTemptargetActive,
+//                    overridePercentage: overridePercentage,
+//                    useOverride: useOverride,
+//                    duration: duration,
+//                    unlimited: unlimited,
+//                    hbt: hbt_,
+//                    overrideTarget: overrideTarget,
+//                    smbIsOff: disableSMBs,
+//                    advancedSettings: overrideArray.first?.advancedSettings ?? false,
+//                    isfAndCr: overrideArray.first?.isfAndCr ?? false,
+//                    isf: overrideArray.first?.isf ?? false,
+//                    cr: overrideArray.first?.cr ?? false,
+//                    smbMinutes: (overrideArray.first?.smbMinutes ?? smbMinutes) as Decimal,
+//                    uamMinutes: (overrideArray.first?.uamMinutes ?? uamMinutes) as Decimal
+//                )
+//                self.storage.save(averages, as: OpenAPS.Monitor.oref2_variables)
+//                return self.loadFileFromStorage(name: Monitor.oref2_variables)
+//            }
+//        }
+//    }
+
     func autosense() async throws -> Autosens? {
         debug(.openAPS, "Start autosens")
 

+ 0 - 9
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -456,15 +456,6 @@ extension Home {
         func openCGM() {
             router.mainSecondaryModalView.send(router.view(for: .cgmDirect))
         }
-
-        func infoPanelTTPercentage(_ hbt_: Double, _ target: Decimal) -> Decimal {
-            guard hbt_ != 0 || target != 0 else {
-                return 0
-            }
-            let c = Decimal(hbt_ - 100)
-            let ratio = min(c / (target + c - 100), maxValue)
-            return (ratio * 100)
-        }
     }
 }
 

+ 44 - 22
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -44,17 +44,21 @@ extension Home {
             fetchLimit: 1
         )) var latestOverride: FetchedResults<OverrideStored>
 
-        @FetchRequest(
-            entity: TempTargets.entity(),
-            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
-        ) var sliderTTpresets: FetchedResults<TempTargets>
-
-        @FetchRequest(
-            entity: TempTargetsSlider.entity(),
-            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
-        ) var enactedSliderTT: FetchedResults<TempTargetsSlider>
-
-        // TODO: end todo
+        @FetchRequest(fetchRequest: TempTargetStored.fetch(
+            NSPredicate.lastActiveTempTarget,
+            ascending: false,
+            fetchLimit: 1
+        )) var latestTempTarget: FetchedResults<TempTargetStored>
+
+//        @FetchRequest(
+//            entity: TempTargets.entity(),
+//            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
+//        ) var sliderTTpresets: FetchedResults<TempTargets>
+//
+//        @FetchRequest(
+//            entity: TempTargetsSlider.entity(),
+//            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
+//        ) var enactedSliderTT: FetchedResults<TempTargetsSlider>
 
         var bolusProgressFormatter: NumberFormatter {
             let formatter = NumberFormatter()
@@ -236,23 +240,41 @@ extension Home {
         }
 
         var tempTargetString: String? {
-            guard let tempTarget = state.tempTarget else {
+            guard let latestTempTarget = latestTempTarget.first else {
                 return nil
             }
-            let target = tempTarget.targetBottom ?? 0
-            let unitString = targetFormatter.string(from: (tempTarget.targetBottom?.asMmolL ?? 0) as NSNumber) ?? ""
-            let rawString = (tirFormatter.string(from: (tempTarget.targetBottom ?? 0) as NSNumber) ?? "") + " " + state.units
+
+            let name = latestTempTarget.name
+            let duration = latestTempTarget.duration
+            let addedMinutes = Int(truncating: duration ?? 0)
+            let date = latestTempTarget.date ?? Date()
+            let newDuration = max(
+                Decimal(Date().distance(to: date.addingTimeInterval(addedMinutes.minutes.timeInterval)).minutes),
+                0
+            )
+            var durationString = ""
+
+            let target = latestTempTarget.target
+            var targetString = target == 0 ? "" : (fetchedTargetFormatter.string(from: (target ?? 0) as NSNumber) ?? "") + " " +
+                state.units
                 .rawValue
 
-            var string = ""
-            if sliderTTpresets.first?.active ?? false {
-                let hbt = sliderTTpresets.first?.hbt ?? 0
-                string = ", " + (tirFormatter.string(from: state.infoPanelTTPercentage(hbt, target) as NSNumber) ?? "") + " %"
+            if newDuration >= 1 {
+                durationString =
+                    "\(newDuration.formatted(.number.grouping(.never).rounded().precision(.fractionLength(0)))) min"
+            } else if newDuration > 0 {
+                durationString =
+                    "\((newDuration * 60).formatted(.number.grouping(.never).rounded().precision(.fractionLength(0)))) s"
+            } else {
+                /// Do not show the Override anymore
+                Task {
+                    guard let objectID = self.latestOverride.first?.objectID else { return }
+                    await state.cancelOverride(withID: objectID)
+                }
             }
 
-            let percentString = state
-                .units == .mmolL ? (unitString + " mmol/L" + string) : (rawString + (string == "0" ? "" : string))
-            return tempTarget.displayName + " " + percentString
+            let components = [targetString, durationString].filter { !$0.isEmpty }
+            return components.isEmpty ? nil : components.joined(separator: ", ")
         }
 
         var infoPanel: some View {

+ 146 - 153
FreeAPS/Sources/Modules/OverrideConfig/OverrideStateModel.swift

@@ -41,7 +41,10 @@ extension OverrideConfig {
         // temp target stuff
         @Published var low: Decimal = 0
         @Published var high: Decimal = 0
-        @Published var durationTT: Decimal = 0
+        @Published var tempTargetDuration: Decimal = 0
+        @Published var tempTargetName: String = ""
+        @Published var tempTargetTarget: Decimal = 0 // lel
+        @Published var isTempTargetEnabled: Bool = false
         @Published var date = Date()
         @Published var newPresetName = ""
         @Published var presetsTT: [TempTarget] = []
@@ -51,6 +54,9 @@ extension OverrideConfig {
         @Published var hbt: Double = 160
         @Published var didSaveSettings: Bool = false
 
+        let coredataContext = CoreDataStack.shared.newTaskContext()
+        let viewContext = CoreDataStack.shared.persistentContainer.viewContext
+
         var alertMessage: String {
             let target: String = units == .mgdL ? "70-270 mg/dl" : "4-15 mmol/l"
             return "Please enter a valid target between" + " \(target)."
@@ -68,9 +74,6 @@ extension OverrideConfig {
             broadcaster.register(SettingsObserver.self, observer: self)
         }
 
-        let coredataContext = CoreDataStack.shared.newTaskContext()
-        let viewContext = CoreDataStack.shared.persistentContainer.viewContext
-
         func isInputInvalid(target: Decimal) -> Bool {
             guard target != 0 else { return false }
 
@@ -428,183 +431,173 @@ extension OverrideConfig.StateModel {
     }
 }
 
-// MARK: - TEMP TARGET
+// MARK: - Temp Targets
 
 extension OverrideConfig.StateModel {
-    func enact() {
-        guard durationTT > 0 else {
-            return
-        }
-        var lowTarget = low
-
-        if viewPercantage {
-            lowTarget = Decimal(round(Double(computeTarget())))
-            coredataContext.performAndWait {
-                let saveToCoreData = TempTargets(context: self.coredataContext)
-                saveToCoreData.id = UUID().uuidString
-                saveToCoreData.active = true
-                saveToCoreData.hbt = hbt
-                saveToCoreData.date = Date()
-                saveToCoreData.duration = durationTT as NSDecimalNumber
-                saveToCoreData.startDate = Date()
-                try? self.coredataContext.save()
-            }
-            didSaveSettings = true
-        } else {
-            coredataContext.performAndWait {
-                let saveToCoreData = TempTargets(context: coredataContext)
-                saveToCoreData.active = false
-                saveToCoreData.date = Date()
-                do {
-                    guard coredataContext.hasChanges else { return }
-                    try coredataContext.save()
-                } catch {
-                    print(error.localizedDescription)
-                }
-            }
+    // Creates and enacts a non Preset Temp Target
+    func saveCustomTempTarget() async {
+        let newTempTarget = TempTargetStored(context: coredataContext)
+        newTempTarget.date = Date()
+        newTempTarget.id = UUID()
+        newTempTarget.enabled = true
+        newTempTarget.duration = tempTargetDuration as NSDecimalNumber
+        newTempTarget.isUploadedToNS = false
+        newTempTarget.name = tempTargetName
+        newTempTarget.target = tempTargetTarget as NSDecimalNumber
+
+        // disable all TempTargets
+
+        // Save Temp Target to Core Data
+        do {
+            guard coredataContext.hasChanges else { return }
+            try coredataContext.save()
+        } catch let error as NSError {
+            debugPrint(
+                "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to save TempTarget to Core Data with error: \(error.userInfo)"
+            )
         }
-        var highTarget = lowTarget
 
-        if units == .mmolL, !viewPercantage {
-            lowTarget = Decimal(round(Double(lowTarget.asMgdL)))
-            highTarget = lowTarget
-        }
+        // Reset State variables
+        await resetTempTargetState()
 
-        let entry = TempTarget(
-            name: TempTarget.custom,
-            createdAt: date,
-            targetTop: highTarget,
-            targetBottom: lowTarget,
-            duration: durationTT,
-            enteredBy: TempTarget.manual,
-            reason: TempTarget.custom
-        )
-        storage.storeTempTargets([entry])
-        showModal(for: nil)
+        // Update View
     }
 
-    func cancel() {
-        storage.storeTempTargets([TempTarget.cancel(at: Date())])
-        showModal(for: nil)
+    // Creates a new Temp Target Preset
+    func saveTempTargetPreset() async {
+        let newTempTarget = TempTargetStored(context: coredataContext)
+        newTempTarget.date = Date()
+        newTempTarget.id = UUID()
+        newTempTarget.enabled = false
+        newTempTarget.duration = tempTargetDuration as NSDecimalNumber
+        newTempTarget.isUploadedToNS = false
+        newTempTarget.name = tempTargetName
+        newTempTarget.target = tempTargetTarget as NSDecimalNumber
 
-        coredataContext.performAndWait {
-            let saveToCoreData = TempTargets(context: self.coredataContext)
-            saveToCoreData.active = false
-            saveToCoreData.date = Date()
-            do {
-                guard coredataContext.hasChanges else { return }
-                try coredataContext.save()
-            } catch {
-                print(error.localizedDescription)
-            }
+        // disable all TempTargets
 
-            let setHBT = TempTargetsSlider(context: self.coredataContext)
-            setHBT.enabled = false
-            setHBT.date = Date()
-            do {
-                guard coredataContext.hasChanges else { return }
-                try coredataContext.save()
-            } catch {
-                print(error.localizedDescription)
-            }
+        // Save Temp Target to Core Data
+        do {
+            guard coredataContext.hasChanges else { return }
+            try coredataContext.save()
+        } catch let error as NSError {
+            debugPrint(
+                "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to save TempTarget to Core Data with error: \(error.userInfo)"
+            )
         }
+
+        // Reset State variables
+        await resetTempTargetState()
+
+        // Update View
     }
 
-    func save() {
-        guard durationTT > 0 else {
-            return
-        }
-        var lowTarget = low
+    // Enact Temp Target Preset
+    /// here we only have to update the Boolean Flag 'enabled'
+    @MainActor func enactTempTargetPreset(withID id: NSManagedObjectID) async {
+        do {
+            /// get the underlying NSManagedObject of the Override that should be enabled
+            let tempTargetToEnact = try viewContext.existingObject(with: id) as? TempTargetStored
+            tempTargetToEnact?.enabled = true
+            tempTargetToEnact?.date = Date()
+            tempTargetToEnact?.isUploadedToNS = false
 
-        if viewPercantage {
-            lowTarget = Decimal(round(Double(computeTarget())))
-            didSaveSettings = true
-        }
-        var highTarget = lowTarget
+            /// Update the 'Cancel Temp Target' button state
+            isTempTargetEnabled = true
+
+            /// disable all active Temp Targets and reset state variables
+            /// do not create a TempTargetRunStored entry because we only want that if we cancel a running Override, not when enacting a Preset
+
+            /// reset state variables
+            await resetTempTargetState()
+
+            guard viewContext.hasChanges else { return }
+            try viewContext.save()
+
+            // Update View
 
-        if units == .mmolL, !viewPercantage {
-            lowTarget = Decimal(round(Double(lowTarget.asMgdL)))
-            highTarget = lowTarget
+        } catch {
+            debugPrint("\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to enact Override Preset")
         }
+    }
+
+    // Disable all active Temp Targets
 
-        let entry = TempTarget(
-            name: newPresetName.isEmpty ? TempTarget.custom : newPresetName,
-            createdAt: Date(),
-            targetTop: highTarget,
-            targetBottom: lowTarget,
-            duration: durationTT,
-            enteredBy: TempTarget.manual,
-            reason: newPresetName.isEmpty ? TempTarget.custom : newPresetName
+    func loadLatestTempTargetConfigurations(fetchLimit: Int) async -> [NSManagedObjectID] {
+        let results = await CoreDataStack.shared.fetchEntitiesAsync(
+            ofType: TempTargetStored.self,
+            onContext: coredataContext,
+            predicate: NSPredicate.lastActiveTempTarget,
+            key: "date",
+            ascending: true,
+            fetchLimit: fetchLimit
         )
-        presetsTT.append(entry)
-        storage.storePresets(presetsTT)
 
-        if viewPercantage {
-            let id = entry.id
-
-            coredataContext.performAndWait {
-                let saveToCoreData = TempTargetsSlider(context: self.coredataContext)
-                saveToCoreData.id = id
-                saveToCoreData.isPreset = true
-                saveToCoreData.enabled = true
-                saveToCoreData.hbt = hbt
-                saveToCoreData.date = Date()
-                saveToCoreData.duration = durationTT as NSDecimalNumber
-                do {
-                    guard coredataContext.hasChanges else { return }
-                    try coredataContext.save()
-                } catch {
-                    print(error.localizedDescription)
-                }
-            }
+        guard let fetchedResults = results as? [TempTargetStored] else { return [] }
+
+        return await coredataContext.perform {
+            return fetchedResults.map(\.objectID)
         }
     }
 
-    func enactPreset(id: String) {
-        if var preset = presetsTT.first(where: { $0.id == id }) {
-            preset.createdAt = Date()
-            storage.storeTempTargets([preset])
-            showModal(for: nil)
-
-            coredataContext.performAndWait {
-                var tempTargetsArray = [TempTargetsSlider]()
-                let requestTempTargets = TempTargetsSlider.fetchRequest() as NSFetchRequest<TempTargetsSlider>
-                let sortTT = NSSortDescriptor(key: "date", ascending: false)
-                requestTempTargets.sortDescriptors = [sortTT]
-                try? tempTargetsArray = coredataContext.fetch(requestTempTargets)
-
-                let whichID = tempTargetsArray.first(where: { $0.id == id })
-
-                if whichID != nil {
-                    let saveToCoreData = TempTargets(context: self.coredataContext)
-                    saveToCoreData.active = true
-                    saveToCoreData.date = Date()
-                    saveToCoreData.hbt = whichID?.hbt ?? 160
-                    // saveToCoreData.id = id
-                    saveToCoreData.startDate = Date()
-                    saveToCoreData.duration = whichID?.duration ?? 0
-
-                    do {
-                        guard coredataContext.hasChanges else { return }
-                        try coredataContext.save()
-                    } catch {
-                        print(error.localizedDescription)
+    @MainActor func disableAllActiveTempTargets(except id: NSManagedObjectID? = nil, createTempTargetRunEntry: Bool) async {
+        // Get ALL NSManagedObject IDs of ALL active Temp Targets to cancel every single Temp Target
+        let ids = await loadLatestTempTargetConfigurations(fetchLimit: 0) // 0 = no fetch limit
+
+        await viewContext.perform {
+            do {
+                // Fetch the existing TempTargetStored objects from the context
+                let results = try ids.compactMap { id in
+                    try self.viewContext.existingObject(with: id) as? TempTargetStored
+                }
+
+                // If there are no results, return early
+                guard !results.isEmpty else { return }
+
+                // Check if we also need to create a corresponding TempTargetRunStored entry, i.e. when the User uses the Cancel Button in Temp Target View
+                if createTempTargetRunEntry {
+                    // Use the first temp target to create a new TempTargetRunStored entry
+                    if let canceledTempTarget = results.first {
+                        let newTempTargetRunStored = TempTargetRunStored(context: self.viewContext)
+                        newTempTargetRunStored.id = UUID()
+                        newTempTargetRunStored.name = canceledTempTarget.name
+                        newTempTargetRunStored.startDate = canceledTempTarget.date ?? .distantPast
+                        newTempTargetRunStored.endDate = Date()
+                        newTempTargetRunStored
+                            .target = canceledTempTarget.target?.decimalValue ?? 0
+                        newTempTargetRunStored.tempTarget = canceledTempTarget
+                        newTempTargetRunStored.isUploadedToNS = false
                     }
-                } else {
-                    let saveToCoreData = TempTargets(context: self.coredataContext)
-                    saveToCoreData.active = false
-                    saveToCoreData.date = Date()
-                    do {
-                        guard coredataContext.hasChanges else { return }
-                        try coredataContext.save()
-                    } catch {
-                        print(error.localizedDescription)
+                }
+
+                // Disable all override except the one with overrideID
+                for tempTargetToCancel in results {
+                    if tempTargetToCancel.objectID != id {
+                        tempTargetToCancel.enabled = false
                     }
                 }
+
+                // Save the context if there are changes
+                if self.viewContext.hasChanges {
+                    try self.viewContext.save()
+
+                    // Update the View
+                    self.updateLatestOverrideConfiguration()
+                }
+            } catch {
+                debugPrint(
+                    "\(DebuggingIdentifiers.failed) \(#file) \(#function) Failed to disable active Overrides with error: \(error.localizedDescription)"
+                )
             }
         }
     }
 
+    @MainActor func resetTempTargetState() async {
+        tempTargetName = ""
+        tempTargetTarget = 0
+        tempTargetDuration = 0
+    }
+
     func removePreset(id: String) {
         presetsTT = presetsTT.filter { $0.id != id }
         storage.storePresets(presetsTT)

+ 163 - 0
FreeAPS/Sources/Modules/OverrideConfig/View/AddTempTargetForm.swift

@@ -0,0 +1,163 @@
+import Foundation
+import SwiftUI
+
+struct AddTempTargetForm: View {
+    @StateObject var state: OverrideConfig.StateModel
+    @Environment(\.presentationMode) var presentationMode
+    @Environment(\.colorScheme) var colorScheme
+    @Environment(\.dismiss) var dismiss
+    @State private var showAlert = false
+    @State private var showPresetAlert = false
+    @State private var alertString = ""
+
+    var color: LinearGradient {
+        colorScheme == .dark ? LinearGradient(
+            gradient: Gradient(colors: [
+                Color.bgDarkBlue,
+                Color.bgDarkerDarkBlue
+            ]),
+            startPoint: .top,
+            endPoint: .bottom
+        )
+            :
+            LinearGradient(
+                gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
+                startPoint: .top,
+                endPoint: .bottom
+            )
+    }
+
+    private var formatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        return formatter
+    }
+
+    private var glucoseFormatter: NumberFormatter {
+        let formatter = NumberFormatter()
+        formatter.numberStyle = .decimal
+        formatter.maximumFractionDigits = 0
+        if state.units == .mmolL {
+            formatter.maximumFractionDigits = 1
+        }
+        formatter.roundingMode = .halfUp
+        return formatter
+    }
+
+    var body: some View {
+        NavigationView {
+            Form {
+                addTempTarget()
+            }.scrollContentBackground(.hidden).background(color)
+                .navigationTitle("Add Override")
+                .navigationBarItems(trailing: Button("Cancel") {
+                    presentationMode.wrappedValue.dismiss()
+                })
+                .alert(
+                    "Start Override",
+                    isPresented: $showAlert,
+                    actions: {
+                        Button("Cancel", role: .cancel) { state.isTempTargetEnabled = false }
+                        Button("Start Temp Target", role: .destructive) {
+                            Task {
+                                await setupAlertString()
+                                state.isTempTargetEnabled.toggle()
+                                await state.saveCustomTempTarget()
+                                await state.resetTempTargetState()
+                                dismiss()
+                            }
+                        }
+                    },
+                    message: {
+                        Text(alertString)
+                    }
+                )
+        }
+    }
+
+    @ViewBuilder private func addTempTarget() -> some View {
+        Section {
+            VStack {
+                TextField("Name", text: $state.overrideName)
+            }
+        } header: {
+            Text("Name")
+        }.listRowBackground(Color.chart)
+
+        Section {
+            HStack {
+                Text("Target")
+                Spacer()
+                TextFieldWithToolBar(text: $state.tempTargetTarget, placeholder: "0", numberFormatter: glucoseFormatter)
+                Text(state.units.rawValue).foregroundColor(.secondary)
+            }
+            HStack {
+                Text("Duration")
+                Spacer()
+                TextFieldWithToolBar(text: $state.tempTargetDuration, placeholder: "0", numberFormatter: formatter)
+                Text("minutes").foregroundColor(.secondary)
+            }
+            DatePicker("Date", selection: $state.date)
+            HStack {
+                Button {
+                    showAlert.toggle()
+                }
+                label: { Text("Enact") }
+                    .disabled(state.tempTargetDuration == 0)
+                    .buttonStyle(BorderlessButtonStyle())
+                    .font(.callout)
+                    .controlSize(.mini)
+
+                Button {
+                    Task {
+                        await state.saveTempTargetPreset()
+                    }
+                }
+                label: { Text("Save as preset") }
+                    .disabled(state.tempTargetDuration == 0)
+                    .tint(.orange)
+                    .frame(maxWidth: .infinity, alignment: .trailing)
+                    .buttonStyle(BorderlessButtonStyle())
+                    .controlSize(.mini)
+            }
+        } header: {
+            Text("Add Custom Temp Target")
+        }.listRowBackground(Color.chart)
+    }
+
+    private func setupAlertString() async {
+        alertString = "\(state.overrideSliderPercentage.formatted(.number)) %, " +
+            (
+                state.overrideDuration > 0 || !state
+                    .indefinite ?
+                    (
+                        state
+                            .overrideDuration
+                            .formatted(.number.grouping(.never).rounded().precision(.fractionLength(0))) +
+                            " min."
+                    ) :
+                    NSLocalizedString(" infinite duration.", comment: "")
+            ) +
+            (
+                (state.target == 0 || !state.shouldOverrideTarget) ? "" :
+                    (" Target: " + state.target.formatted() + " " + state.units.rawValue + ".")
+            )
+            +
+            (
+                state
+                    .smbIsOff ?
+                    NSLocalizedString(
+                        " SMBs are disabled either by schedule or during the entire duration.",
+                        comment: ""
+                    ) : ""
+            )
+            +
+            "\n\n"
+            +
+            NSLocalizedString(
+                "Starting this override will change your profiles and/or your Target Glucose used for looping during the entire selected duration. Tapping ”Start Override” will start your new Override or edit your current active Override.",
+                comment: ""
+            )
+    }
+}

+ 121 - 180
FreeAPS/Sources/Modules/OverrideConfig/View/OverrideRootView.swift

@@ -10,12 +10,14 @@ extension OverrideConfig {
 
         @State private var isEditing = false
         @State private var showOverrideCreationSheet = false
+        @State private var showTempTargetCreationSheet = false
         @State private var showingDetail = false
         @State private var showCheckmark: Bool = false
         @State private var selectedPresetID: String?
         @State private var selectedOverride: OverrideStored?
+        @State private var selectedTempTarget: OverrideStored?
+
         // temp targets
-        @State private var isPromptPresented = false
         @State private var isRemoveAlertPresented = false
         @State private var removeAlert: Alert?
         @State private var isEditingTT = false
@@ -39,11 +41,6 @@ extension OverrideConfig {
                 )
         }
 
-        @FetchRequest(
-            entity: TempTargetsSlider.entity(),
-            sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)]
-        ) var isEnabledArray: FetchedResults<TempTargetsSlider>
-
         private var formatter: NumberFormatter {
             let formatter = NumberFormatter()
             formatter.numberStyle = .decimal
@@ -91,8 +88,15 @@ extension OverrideConfig {
                                         Image(systemName: "plus")
                                     }
                                 })
-                            default:
-                                EmptyView()
+                            case .tempTargets:
+                                Button(action: {
+                                    showTempTargetCreationSheet = true
+                                }, label: {
+                                    HStack {
+                                        Text("Add Temp Target")
+                                        Image(systemName: "plus")
+                                    }
+                                })
                             }
                         }
                     }
@@ -115,6 +119,14 @@ extension OverrideConfig {
                     }) {
                         AddOverrideForm(state: state)
                     }
+                    .sheet(isPresented: $showTempTargetCreationSheet, onDismiss: {
+                        Task {
+                            await state.resetStateVariables()
+                            showTempTargetCreationSheet = false
+                        }
+                    }) {
+                        AddOverrideForm(state: state)
+                    }
             }.background(color)
         }
 
@@ -134,11 +146,38 @@ extension OverrideConfig {
             }
         }
 
+        @ViewBuilder func tempTargets() -> some View {
+            if state.presetsTT.isNotEmpty {
+                overridePresets
+            } else {
+                defaultText
+            }
+//
+//            if state.isEnabled, state.activeOverrideName.isNotEmpty {
+//                currentActiveOverride
+//            }
+//
+//            if state.overridePresets.isNotEmpty || state.currentActiveOverride != nil {
+//                cancelOverrideButton
+//            }
+        }
+
         private var defaultText: some View {
-            Section {} header: {
-                Text("Add Preset or Override by tapping 'Add Override +' in the top right-hand corner of the screen.")
+            switch state.selectedTab {
+            case .overrides:
+                Section {} header: {
+                    Text("Add Preset or Override by tapping 'Add Override +' in the top right-hand corner of the screen.")
+                        .textCase(nil)
+                        .foregroundStyle(.secondary)
+                }
+            case .tempTargets:
+                Section {} header: {
+                    Text(
+                        "Add Preset or Temp Target by tapping 'Add Temp Target +' in the top right-hand corner of the screen."
+                    )
                     .textCase(nil)
                     .foregroundStyle(.secondary)
+                }
             }
         }
 
@@ -177,6 +216,41 @@ extension OverrideConfig {
             }
         }
 
+        private var tempTargetPresets: some View {
+            Section {
+                ForEach(state.presetsTT) { preset in
+                    tempTargetView(for: preset)
+                        .swipeActions(edge: .trailing, allowsFullSwipe: true) {
+                            Button(role: .none) {
+                                Task {
+//                                    await state.invokeOverridePresetDeletion(preset.objectID)
+                                }
+                            } label: {
+                                Label("Delete", systemImage: "trash")
+                                    .tint(.red)
+                            }
+                            Button(action: {
+                                // Set the selected Override to the chosen Preset and pass it to the Edit Sheet
+//                                selectedOverride = preset
+//                                state.showOverrideEditSheet = true
+                            }, label: {
+                                Label("Edit", systemImage: "pencil")
+                                    .tint(.blue)
+                            })
+                        }
+                }
+                .onMove(perform: state.reorderOverride)
+                .listRowBackground(Color.chart)
+            } header: {
+                Text("Presets")
+            } footer: {
+                HStack {
+                    Image(systemName: "hand.draw.fill")
+                    Text("Swipe left to edit or delete an override preset. Hold, drag and drop to reorder a preset.")
+                }
+            }
+        }
+
         private var currentActiveOverride: some View {
             Section {
                 HStack {
@@ -205,175 +279,41 @@ extension OverrideConfig {
         }
 
         private var cancelOverrideButton: some View {
-            Button(action: {
-                Task {
-                    // Save cancelled Override in OverrideRunStored Entity
-                    // Cancel ALL active Override
-                    await state.disableAllActiveOverrides(createOverrideRunEntry: true)
-                }
-            }, label: {
-                Text("Cancel Override")
-
-            })
-                .frame(maxWidth: .infinity, alignment: .center)
-                .disabled(!state.isEnabled)
-                .listRowBackground(!state.isEnabled ? Color(.systemGray4) : Color(.systemRed))
-                .tint(.white)
-        }
-
-        @ViewBuilder func tempTargets() -> some View {
-            if !state.presetsTT.isEmpty {
-                Section(header: Text("Presets")) {
-                    ForEach(state.presetsTT) { preset in
-                        presetView(for: preset)
+            switch state.selectedTab {
+            case .overrides:
+                Button(action: {
+                    Task {
+                        // Save cancelled Override in OverrideRunStored Entity
+                        // Cancel ALL active Override
+                        await state.disableAllActiveOverrides(createOverrideRunEntry: true)
                     }
-                }.listRowBackground(Color.chart)
-            }
-
-            HStack {
-                Text("Experimental")
-                Toggle(isOn: $state.viewPercantage) {}.controlSize(.mini)
-                Image(systemName: "figure.highintensity.intervaltraining")
-                Image(systemName: "fork.knife")
-            }.listRowBackground(Color.chart)
+                }, label: {
+                    Text("Cancel Override")
 
-            if state.viewPercantage {
-                Section {
-                    VStack {
-                        Text("\(state.percentageTT.formatted(.number)) % Insulin")
-                            .foregroundColor(isEditingTT ? .orange : .blue)
-                            .font(.largeTitle)
-                            .padding(.vertical)
-                        Slider(
-                            value: $state.percentageTT,
-                            in: 15 ...
-                                min(Double(state.maxValue * 100), 200),
-                            step: 1,
-                            onEditingChanged: { editing in
-                                isEditingTT = editing
-                            }
-                        )
-                        // Only display target slider when not 100 %
-                        if state.percentageTT != 100 {
-                            Spacer()
-                            Divider()
-                            Text(
-                                (
-                                    state
-                                        .units == .mmolL ?
-                                        "\(state.computeTarget().asMmolL.formatted(.number.grouping(.never).rounded().precision(.fractionLength(1)))) mmol/L" :
-                                        "\(state.computeTarget().formatted(.number.grouping(.never).rounded().precision(.fractionLength(0)))) mg/dl"
-                                )
-                                    + NSLocalizedString(" Target Glucose", comment: "")
-                            )
-                            .foregroundColor(.green)
-                            .padding(.vertical)
-
-                            Slider(
-                                value: $state.hbt,
-                                in: 101 ... 295,
-                                step: 1
-                            ).accentColor(.green)
-                        }
-                    }
-                }.listRowBackground(Color.chart)
-            } else {
-                Section(header: Text("Custom")) {
-                    HStack {
-                        Text("Target")
-                        Spacer()
-                        TextFieldWithToolBar(text: $state.low, placeholder: "0", numberFormatter: glucoseFormatter)
-                        Text(state.units.rawValue).foregroundColor(.secondary)
-                    }
-                    HStack {
-                        Text("Duration")
-                        Spacer()
-                        TextFieldWithToolBar(text: $state.durationTT, placeholder: "0", numberFormatter: formatter)
-                        Text("minutes").foregroundColor(.secondary)
-                    }
-                    DatePicker("Date", selection: $state.date)
-                    HStack {
-                        Button { state.enact() }
-                        label: { Text("Enact") }
-                            .disabled(state.durationTT == 0)
-                            .buttonStyle(BorderlessButtonStyle())
-                            .font(.callout)
-                            .controlSize(.mini)
-
-                        Button { isPromptPresented = true }
-                        label: { Text("Save as preset") }
-                            .disabled(state.durationTT == 0)
-                            .tint(.orange)
-                            .frame(maxWidth: .infinity, alignment: .trailing)
-                            .buttonStyle(BorderlessButtonStyle())
-                            .controlSize(.mini)
-                    }
-                }.listRowBackground(Color.chart)
-            }
-            if state.viewPercantage {
-                Section {
-                    HStack {
-                        Text("Duration")
-                        Spacer()
-                        TextFieldWithToolBar(text: $state.durationTT, placeholder: "0", numberFormatter: formatter)
-                        Text("minutes").foregroundColor(.secondary)
-                    }
-                    DatePicker("Date", selection: $state.date)
-                    HStack {
-                        Button { state.enact() }
-                        label: { Text("Enact") }
-                            .disabled(state.durationTT == 0)
-                            .buttonStyle(BorderlessButtonStyle())
-                            .font(.callout)
-                            .controlSize(.mini)
-
-                        Button { isPromptPresented = true }
-                        label: { Text("Save as preset") }
-                            .disabled(state.durationTT == 0)
-                            .tint(.orange)
-                            .frame(maxWidth: .infinity, alignment: .trailing)
-                            .buttonStyle(BorderlessButtonStyle())
-                            .controlSize(.mini)
+                })
+                    .frame(maxWidth: .infinity, alignment: .center)
+                    .disabled(!state.isEnabled)
+                    .listRowBackground(!state.isEnabled ? Color(.systemGray4) : Color(.systemRed))
+                    .tint(.white)
+            case .tempTargets:
+                Button(action: {
+                    Task {
+                        // Save cancelled Temp Targets in TempTargetRunStored Entity
+                        // Cancel ALL active Temp Targets
+                        await state.disableAllActiveTempTargets(createTempTargetRunEntry: true)
                     }
-                }.listRowBackground(Color.chart)
-            }
+                }, label: {
+                    Text("Cancel Temp Target")
 
-            Section {
-                Button { state.cancel() }
-                label: {
-                    HStack {
-                        Spacer()
-                        Text("Cancel Temp Target")
-                        Spacer()
-                        Image(systemName: "xmark.app")
-                            .font(.title)
-                    }
-                }
-                .frame(maxWidth: .infinity, alignment: .center)
-                .disabled(state.storage.current() == nil)
-                .listRowBackground(state.storage.current() == nil ? Color(.systemGray4) : Color(.systemRed))
-                .tint(.white)
-            }.popover(isPresented: $isPromptPresented) {
-                Form {
-                    Section(header: Text("Enter preset name")) {
-                        TextField("Name", text: $state.newPresetName)
-                        Button {
-                            state.save()
-                            isPromptPresented = false
-                        }
-                        label: { Text("Save") }
-                        Button { isPromptPresented = false }
-                        label: { Text("Cancel") }
-                    }
-                }
-            }
-            .onAppear {
-                configureView()
-                state.hbt = isEnabledArray.first?.hbt ?? 160
+                })
+                    .frame(maxWidth: .infinity, alignment: .center)
+                    .disabled(!state.isTempTargetEnabled)
+                    .listRowBackground(!state.isTempTargetEnabled ? Color(.systemGray4) : Color(.systemRed))
+                    .tint(.white)
             }
         }
 
-        private func presetView(for preset: TempTarget) -> some View {
+        private func tempTargetView(for preset: TempTarget) -> some View {
             var low = preset.targetBottom
             var high = preset.targetTop
             if state.units == .mmolL {
@@ -414,14 +354,15 @@ extension OverrideConfig {
                     }
                     .contentShape(Rectangle())
                     .onTapGesture {
-                        state.enactPreset(id: preset.id)
-                        selectedPresetID = preset.id
-                        showCheckmark.toggle()
-
-                        // deactivate showCheckmark after 3 seconds
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
-                            showCheckmark = false
-                        }
+                        // TODO: - adapt to Temp Targets
+//                        state.enactPreset(id: preset.id)
+//                        selectedPresetID = preset.id
+//                        showCheckmark.toggle()
+//
+//                        // deactivate showCheckmark after 3 seconds
+//                        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
+//                            showCheckmark = false
+//                        }
                     }
 
                     Image(systemName: "xmark.circle").foregroundColor(showCheckmark && isSelected ? Color.clear : Color.secondary)

+ 0 - 1
FreeAPS/Sources/Services/Calendar/CalendarManager.swift

@@ -252,7 +252,6 @@ final class BaseCalendarManager: CalendarManager, Injectable {
                     settingsManager.settings.units == .mmolL ? Int(lastGlucoseValue)
                         .asMmolL : Decimal(lastGlucoseValue)
                 ) as NSNumber)!
-            debugPrint("\(DebuggingIdentifiers.failed) glucose text: \(glucoseText)")
 
             let directionText = lastGlucoseObject.directionEnum?.symbol ?? "↔︎"
 

+ 14 - 12
FreeAPS/Sources/Shortcuts/TempPresets/TempPresetsIntentRequest.swift

@@ -32,28 +32,30 @@ import Foundation
         return tempOneTarget
     }
 
+    // TODO: - probably broken for now...
+
     func enactTempTarget(_ presetTarget: TempTarget) throws -> TempTarget {
         var tempTarget = presetTarget
         tempTarget.createdAt = Date()
         storage.storeTempTargets([tempTarget])
 
         coredataContext.performAndWait {
-            var tempTargetsArray = [TempTargetsSlider]()
-            let requestTempTargets = TempTargetsSlider.fetchRequest() as NSFetchRequest<TempTargetsSlider>
+            var tempTargetsArray = [TempTargetStored]()
+            let requestTempTargets = TempTargetStored.fetchRequest() as NSFetchRequest<TempTargetStored>
             let sortTT = NSSortDescriptor(key: "date", ascending: false)
             requestTempTargets.sortDescriptors = [sortTT]
             if coredataContext.hasChanges {
                 try? tempTargetsArray = coredataContext.fetch(requestTempTargets)
             }
 
-            let whichID = tempTargetsArray.first(where: { $0.id == tempTarget.id })
+            let whichID = tempTargetsArray.first(where: { $0.id == UUID(uuidString: tempTarget.id) })
 
             if whichID != nil {
-                let saveToCoreData = TempTargets(context: self.coredataContext)
-                saveToCoreData.active = true
+                let saveToCoreData = TempTargetStored(context: self.coredataContext)
+                saveToCoreData.enabled = true
+                saveToCoreData.date = Date()
+                saveToCoreData.target = whichID?.target ?? 160
                 saveToCoreData.date = Date()
-                saveToCoreData.hbt = whichID?.hbt ?? 160
-                saveToCoreData.startDate = Date()
                 saveToCoreData.duration = whichID?.duration ?? 0
 
                 do {
@@ -63,8 +65,8 @@ import Foundation
                     print(error.localizedDescription)
                 }
             } else {
-                let saveToCoreData = TempTargets(context: self.coredataContext)
-                saveToCoreData.active = false
+                let saveToCoreData = TempTargetStored(context: self.coredataContext)
+                saveToCoreData.enabled = false
                 saveToCoreData.date = Date()
                 do {
                     guard coredataContext.hasChanges else { return }
@@ -81,14 +83,14 @@ import Foundation
     func cancelTempTarget() throws {
         storage.storeTempTargets([TempTarget.cancel(at: Date())])
         try coredataContext.performAndWait {
-            let saveToCoreData = TempTargets(context: self.coredataContext)
-            saveToCoreData.active = false
+            let saveToCoreData = TempTargetStored(context: self.coredataContext)
+            saveToCoreData.enabled = false
             saveToCoreData.date = Date()
             if coredataContext.hasChanges {
                 try self.coredataContext.save()
             }
 
-            let setHBT = TempTargetsSlider(context: self.coredataContext)
+            let setHBT = TempTargetStored(context: self.coredataContext)
             setHBT.enabled = false
             setHBT.date = Date()
             if coredataContext.hasChanges {

+ 0 - 4
Model/Classes+Properties/TempTargets+CoreDataClass.swift

@@ -1,4 +0,0 @@
-import CoreData
-import Foundation
-
-@objc(TempTargets) public class TempTargets: NSManagedObject {}

+ 0 - 17
Model/Classes+Properties/TempTargets+CoreDataProperties.swift

@@ -1,17 +0,0 @@
-import CoreData
-import Foundation
-
-public extension TempTargets {
-    @nonobjc class func fetchRequest() -> NSFetchRequest<TempTargets> {
-        NSFetchRequest<TempTargets>(entityName: "TempTargets")
-    }
-
-    @NSManaged var active: Bool
-    @NSManaged var date: Date?
-    @NSManaged var duration: NSDecimalNumber?
-    @NSManaged var hbt: Double
-    @NSManaged var id: String?
-    @NSManaged var startDate: Date?
-}
-
-extension TempTargets: Identifiable {}

+ 0 - 4
Model/Classes+Properties/TempTargetsSlider+CoreDataClass.swift

@@ -1,4 +0,0 @@
-import CoreData
-import Foundation
-
-@objc(TempTargetsSlider) public class TempTargetsSlider: NSManagedObject {}

+ 0 - 18
Model/Classes+Properties/TempTargetsSlider+CoreDataProperties.swift

@@ -1,18 +0,0 @@
-import CoreData
-import Foundation
-
-public extension TempTargetsSlider {
-    @nonobjc class func fetchRequest() -> NSFetchRequest<TempTargetsSlider> {
-        NSFetchRequest<TempTargetsSlider>(entityName: "TempTargetsSlider")
-    }
-
-    @NSManaged var date: Date?
-    @NSManaged var defaultHBT: Double
-    @NSManaged var duration: NSDecimalNumber?
-    @NSManaged var enabled: Bool
-    @NSManaged var hbt: Double
-    @NSManaged var id: String?
-    @NSManaged var isPreset: Bool
-}
-
-extension TempTargetsSlider: Identifiable {}

+ 25 - 0
Model/Helper/TempTargetStored+Helper.swift

@@ -0,0 +1,25 @@
+import CoreData
+import Foundation
+
+extension NSPredicate {
+    static var lastActiveTempTarget: NSPredicate {
+        let date = Date.oneDayAgo
+        return NSPredicate(
+            format: "date >= %@ AND enabled == %@",
+            date as NSDate,
+            true as NSNumber
+        )
+    }
+}
+
+extension TempTargetStored {
+    static func fetch(_ predicate: NSPredicate, ascending: Bool, fetchLimit: Int? = nil) -> NSFetchRequest<TempTargetStored> {
+        let request = TempTargetStored.fetchRequest()
+        request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: ascending)]
+        request.predicate = predicate
+        if let fetchLimit = fetchLimit {
+            request.fetchLimit = fetchLimit
+        }
+        return request
+    }
+}

+ 20 - 14
Model/TrioCoreDataPersistentContainer.xcdatamodeld/TrioCoreDataPersistentContainer.xcdatamodel/contents

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22757" systemVersion="23G93" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
+<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G120" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
     <entity name="BolusStored" representedClassName="BolusStored" syncable="YES">
         <attribute name="amount" optional="YES" attributeType="Decimal" defaultValueString="0"/>
         <attribute name="isExternal" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
@@ -185,27 +185,33 @@
         <attribute name="tempType" optional="YES" attributeType="String"/>
         <relationship name="pumpEvent" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PumpEventStored" inverseName="tempBasal" inverseEntity="PumpEventStored"/>
     </entity>
-    <entity name="TempTargets" representedClassName="TempTargets" syncable="YES">
-        <attribute name="active" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
-        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
-        <attribute name="duration" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
-        <attribute name="hbt" optional="YES" attributeType="Double" defaultValueString="160" usesScalarValueType="YES"/>
-        <attribute name="id" optional="YES" attributeType="String"/>
+    <entity name="TempTargetRunStored" representedClassName="TempTargetRunStored" syncable="YES">
+        <attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="id" optional="YES" attributeType="UUID" defaultValueString="empy" usesScalarValueType="NO"/>
+        <attribute name="isUploadedToNS" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
+        <attribute name="name" optional="YES" attributeType="String"/>
         <attribute name="startDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="target" optional="YES" attributeType="Decimal" defaultValueString="160"/>
+        <relationship name="tempTarget" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TempTargetStored" inverseName="tempTargetRun" inverseEntity="TempTargetStored"/>
         <fetchIndex name="byDate">
-            <fetchIndexElement property="date" type="Binary" order="descending"/>
+            <fetchIndexElement property="startDate" type="Binary" order="descending"/>
         </fetchIndex>
     </entity>
-    <entity name="TempTargetsSlider" representedClassName="TempTargetsSlider" syncable="YES">
+    <entity name="TempTargetStored" representedClassName="TempTargetStored" syncable="YES">
         <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
-        <attribute name="defaultHBT" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
         <attribute name="duration" optional="YES" attributeType="Decimal" defaultValueString="0.0"/>
-        <attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="100" usesScalarValueType="YES"/>
-        <attribute name="hbt" optional="YES" attributeType="Double" defaultValueString="160" usesScalarValueType="YES"/>
-        <attribute name="id" optional="YES" attributeType="String" defaultValueString="empy"/>
-        <attribute name="isPreset" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
+        <attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
+        <attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
+        <attribute name="isPreset" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
+        <attribute name="isUploadedToNS" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
+        <attribute name="name" optional="YES" attributeType="String"/>
+        <attribute name="target" optional="YES" attributeType="Decimal" defaultValueString="160"/>
+        <relationship name="tempTargetRun" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TempTargetRunStored" inverseName="tempTarget" inverseEntity="TempTargetRunStored"/>
         <fetchIndex name="byDate">
             <fetchIndexElement property="date" type="Binary" order="descending"/>
         </fetchIndex>
+        <fetchIndex name="byIsPreset">
+            <fetchIndexElement property="isPreset" type="Binary" order="descending"/>
+        </fetchIndex>
     </entity>
 </model>

+ 4 - 0
TempTargetRunStored+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(TempTargetRunStored) public class TempTargetRunStored: NSManagedObject {}

+ 18 - 0
TempTargetRunStored+CoreDataProperties.swift

@@ -0,0 +1,18 @@
+import CoreData
+import Foundation
+
+public extension TempTargetRunStored {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<TempTargetRunStored> {
+        NSFetchRequest<TempTargetRunStored>(entityName: "TempTargetRunStored")
+    }
+
+    @NSManaged var startDate: Date?
+    @NSManaged var target: Decimal
+    @NSManaged var id: UUID?
+    @NSManaged var endDate: Date?
+    @NSManaged var isUploadedToNS: Bool
+    @NSManaged var tempTarget: TempTargetStored?
+    @NSManaged var name: String?
+}
+
+extension TempTargetRunStored: Identifiable {}

+ 4 - 0
TempTargetStored+CoreDataClass.swift

@@ -0,0 +1,4 @@
+import CoreData
+import Foundation
+
+@objc(TempTargetStored) public class TempTargetStored: NSManagedObject {}

+ 20 - 0
TempTargetStored+CoreDataProperties.swift

@@ -0,0 +1,20 @@
+import CoreData
+import Foundation
+
+public extension TempTargetStored {
+    @nonobjc class func fetchRequest() -> NSFetchRequest<TempTargetStored> {
+        NSFetchRequest<TempTargetStored>(entityName: "TempTargetStored")
+    }
+
+    @NSManaged var enabled: Bool
+    @NSManaged var date: Date?
+    @NSManaged var duration: NSDecimalNumber?
+    @NSManaged var target: NSDecimalNumber?
+    @NSManaged var id: UUID?
+    @NSManaged var name: String?
+    @NSManaged var isUploadedToNS: Bool
+    @NSManaged var isPreset: Bool
+    @NSManaged var tempTargetRun: TempTargetRunStored?
+}
+
+extension TempTargetStored: Identifiable {}