Преглед изворни кода

Improve the basal manual temp : allows to do bolus, new UI, persistant basal temp.
compile with the Xcode Version 14

avouspierre пре 3 година
родитељ
комит
56c4ff81f7

+ 6 - 19
FreeAPS.xcodeproj/xcshareddata/xcschemes/FreeAPSWatch.xcscheme

@@ -55,10 +55,8 @@
       debugServiceExtension = "internal"
       allowLocationSimulation = "YES"
       notificationPayloadFile = "FreeAPSWatch WatchKit Extension/PushNotificationPayload.apns">
-      <RemoteRunnable
-         runnableDebuggingMode = "2"
-         BundleIdentifier = "com.apple.Carousel"
-         RemotePath = "/FreeAPS X">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "38E8751B27554D5500975559"
@@ -66,7 +64,7 @@
             BlueprintName = "FreeAPSWatch"
             ReferencedContainer = "container:FreeAPS.xcodeproj">
          </BuildableReference>
-      </RemoteRunnable>
+      </BuildableProductRunnable>
    </LaunchAction>
    <ProfileAction
       buildConfiguration = "Release"
@@ -74,10 +72,8 @@
       savedToolIdentifier = ""
       useCustomWorkingDirectory = "NO"
       debugDocumentVersioning = "YES">
-      <RemoteRunnable
-         runnableDebuggingMode = "2"
-         BundleIdentifier = "com.apple.Carousel"
-         RemotePath = "/FreeAPS X">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "38E8751B27554D5500975559"
@@ -85,16 +81,7 @@
             BlueprintName = "FreeAPSWatch"
             ReferencedContainer = "container:FreeAPS.xcodeproj">
          </BuildableReference>
-      </RemoteRunnable>
-      <MacroExpansion>
-         <BuildableReference
-            BuildableIdentifier = "primary"
-            BlueprintIdentifier = "38E8751B27554D5500975559"
-            BuildableName = "FreeAPSWatch.app"
-            BlueprintName = "FreeAPSWatch"
-            ReferencedContainer = "container:FreeAPS.xcodeproj">
-         </BuildableReference>
-      </MacroExpansion>
+      </BuildableProductRunnable>
    </ProfileAction>
    <AnalyzeAction
       buildConfiguration = "Debug">

+ 74 - 60
FreeAPS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -151,6 +151,66 @@
       "size" : "1024x1024"
     },
     {
+      "filename" : "16.png",
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "16x16"
+    },
+    {
+      "filename" : "32.png",
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "16x16"
+    },
+    {
+      "filename" : "32.png",
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "32x32"
+    },
+    {
+      "filename" : "64.png",
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "32x32"
+    },
+    {
+      "filename" : "128.png",
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "128x128"
+    },
+    {
+      "filename" : "256.png",
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "128x128"
+    },
+    {
+      "filename" : "256.png",
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "256x256"
+    },
+    {
+      "filename" : "512.png",
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "256x256"
+    },
+    {
+      "filename" : "512.png",
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "512x512"
+    },
+    {
+      "filename" : "1024.png",
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "512x512"
+    },
+    {
       "filename" : "48.png",
       "idiom" : "watch",
       "role" : "notificationCenter",
@@ -226,6 +286,13 @@
       "subtype" : "45mm"
     },
     {
+      "idiom" : "watch",
+      "role" : "appLauncher",
+      "scale" : "2x",
+      "size" : "54x54",
+      "subtype" : "49mm"
+    },
+    {
       "filename" : "172.png",
       "idiom" : "watch",
       "role" : "quickLook",
@@ -257,70 +324,17 @@
       "subtype" : "45mm"
     },
     {
-      "filename" : "1024.png",
-      "idiom" : "watch-marketing",
-      "scale" : "1x",
-      "size" : "1024x1024"
-    },
-    {
-      "filename" : "16.png",
-      "idiom" : "mac",
-      "scale" : "1x",
-      "size" : "16x16"
-    },
-    {
-      "filename" : "32.png",
-      "idiom" : "mac",
-      "scale" : "2x",
-      "size" : "16x16"
-    },
-    {
-      "filename" : "32.png",
-      "idiom" : "mac",
-      "scale" : "1x",
-      "size" : "32x32"
-    },
-    {
-      "filename" : "64.png",
-      "idiom" : "mac",
-      "scale" : "2x",
-      "size" : "32x32"
-    },
-    {
-      "filename" : "128.png",
-      "idiom" : "mac",
-      "scale" : "1x",
-      "size" : "128x128"
-    },
-    {
-      "filename" : "256.png",
-      "idiom" : "mac",
-      "scale" : "2x",
-      "size" : "128x128"
-    },
-    {
-      "filename" : "256.png",
-      "idiom" : "mac",
-      "scale" : "1x",
-      "size" : "256x256"
-    },
-    {
-      "filename" : "512.png",
-      "idiom" : "mac",
+      "idiom" : "watch",
+      "role" : "quickLook",
       "scale" : "2x",
-      "size" : "256x256"
-    },
-    {
-      "filename" : "512.png",
-      "idiom" : "mac",
-      "scale" : "1x",
-      "size" : "512x512"
+      "size" : "129x129",
+      "subtype" : "49mm"
     },
     {
       "filename" : "1024.png",
-      "idiom" : "mac",
-      "scale" : "2x",
-      "size" : "512x512"
+      "idiom" : "watch-marketing",
+      "scale" : "1x",
+      "size" : "1024x1024"
     }
   ],
   "info" : {

+ 38 - 0
FreeAPS/Resources/Assets.xcassets/Colors/ManualTempBasal.colorset/Contents.json

@@ -0,0 +1,38 @@
+{
+  "colors" : [
+    {
+      "color" : {
+        "color-space" : "srgb",
+        "components" : {
+          "alpha" : "1.000",
+          "blue" : "0.988",
+          "green" : "0.588",
+          "red" : "0.118"
+        }
+      },
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "color" : {
+        "color-space" : "srgb",
+        "components" : {
+          "alpha" : "1.000",
+          "blue" : "0.988",
+          "green" : "0.588",
+          "red" : "0.118"
+        }
+      },
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 19 - 6
FreeAPS/Sources/APS/APSManager.swift

@@ -88,7 +88,7 @@ final class BaseAPSManager: APSManager, Injectable {
 
     var bluetoothManager: BluetoothStateManager? { deviceDataManager.bluetoothManager }
 
-    var isManualTempBasal: Bool = false
+    @Persisted(key: "isManualTempBasal") var isManualTempBasal: Bool = false
 
     let isLooping = CurrentValueSubject<Bool, Never>(false)
     let lastLoopDateSubject = PassthroughSubject<Date, Never>()
@@ -241,11 +241,6 @@ final class BaseAPSManager: APSManager, Injectable {
             return APSError.invalidPumpState(message: "Pump suspended")
         }
 
-        // block all if manual temp basal
-        if isManualTempBasal {
-            return APSError.manualBasalTemp(message: "Unable to change anything")
-        }
-
         let reservoir = storage.retrieve(OpenAPS.Monitor.reservoir, as: Decimal.self) ?? 100
         guard reservoir > 0 else {
             return APSError.invalidPumpState(message: "Reservoir is empty")
@@ -415,6 +410,13 @@ final class BaseAPSManager: APSManager, Injectable {
         }
 
         guard let pump = pumpManager else { return }
+
+        // unable to do temp basal during manual temp basal 😁
+        if isManualTempBasal {
+            processError(APSError.manualBasalTemp(message: "Loop not possible during the manual basal temp"))
+            return
+        }
+
         debug(.apsManager, "Enact temp basal \(rate) - \(duration)")
 
         let roundedAmout = pump.roundToSupportedBasalRate(unitsPerHour: rate)
@@ -529,6 +531,11 @@ final class BaseAPSManager: APSManager, Injectable {
                 processError(error)
                 return
             }
+            // unable to do temp basal during manual temp basal 😁
+            if isManualTempBasal {
+                processError(APSError.manualBasalTemp(message: "Loop not possible during the manual basal temp"))
+                return
+            }
             guard !settings.closedLoop else {
                 return
             }
@@ -580,6 +587,12 @@ final class BaseAPSManager: APSManager, Injectable {
             return Fail(error: APSError.apsError(message: "Pump not set")).eraseToAnyPublisher()
         }
 
+        // unable to do temp basal during manual temp basal 😁
+        if isManualTempBasal {
+            return Fail(error: APSError.manualBasalTemp(message: "Loop not possible during the manual basal temp"))
+                .eraseToAnyPublisher()
+        }
+
         let basalPublisher: AnyPublisher<Void, Error> = Deferred { () -> AnyPublisher<Void, Error> in
             if let error = self.verifyStatus() {
                 return Fail(error: error).eraseToAnyPublisher()

+ 1 - 0
FreeAPS/Sources/Helpers/Color+Extensions.swift

@@ -52,6 +52,7 @@ extension Color {
     static let loopGreen = Color("LoopGreen")
     static let loopYellow = Color("LoopYellow")
     static let loopRed = Color("LoopRed")
+    static let loopManualTemp = Color("ManualTempBasal")
     //   static let insulin = Color("Insulin")
     static let uam = Color("UAM")
     static let zt = Color("ZT")

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

@@ -47,6 +47,7 @@ extension Home {
         @Published var pumpDisplayState: PumpDisplayState?
         @Published var alarm: GlucoseAlarm?
         @Published var animatedBackground = false
+        @Published var manualTempBasal = false
 
         override func subscribe() {
             setupGlucose()
@@ -68,6 +69,7 @@ extension Home {
             lastLoopDate = apsManager.lastLoopDate
             carbsRequired = suggestion?.carbsReq
             alarm = provider.glucoseStorage.alarm
+            manualTempBasal = apsManager.isManualTempBasal
 
             setStatusTitle()
             setupCurrentTempTarget()
@@ -197,6 +199,7 @@ extension Home {
         private func setupBasals() {
             DispatchQueue.main.async { [weak self] in
                 guard let self = self else { return }
+                self.manualTempBasal = self.apsManager.isManualTempBasal
                 self.tempBasals = self.provider.pumpHistory(hours: self.filteredHours).filter {
                     $0.type == .tempBasal || $0.type == .tempBasalDuration
                 }
@@ -260,6 +263,7 @@ extension Home {
         private func setupTempTargets() {
             DispatchQueue.main.async { [weak self] in
                 guard let self = self else { return }
+                self.manualTempBasal = self.apsManager.isManualTempBasal
                 self.tempTargets = self.provider.tempTargets(hours: self.filteredHours)
             }
         }
@@ -357,6 +361,7 @@ extension Home.StateModel:
         closedLoop = settingsManager.settings.closedLoop
         units = settingsManager.settings.units
         animatedBackground = settingsManager.settings.animatedBackground
+        manualTempBasal = apsManager.isManualTempBasal
         setupGlucose()
     }
 

+ 7 - 1
FreeAPS/Sources/Modules/Home/View/Header/LoopView.swift

@@ -13,6 +13,7 @@ struct LoopView: View {
     @Binding var timerDate: Date
     @Binding var isLooping: Bool
     @Binding var lastLoopDate: Date
+    @Binding var manualTempBasal: Bool
 
     private var dateFormatter: DateFormatter {
         let formatter = DateFormatter()
@@ -34,6 +35,8 @@ struct LoopView: View {
             }
             if isLooping {
                 Text("looping").font(.caption2)
+            } else if manualTempBasal {
+                Text("Manual").font(.caption2)
             } else if actualSuggestion?.timestamp != nil {
                 Text(timeString).font(.caption2)
                     .foregroundColor(.secondary)
@@ -55,6 +58,9 @@ struct LoopView: View {
         guard actualSuggestion?.timestamp != nil else {
             return .loopGray
         }
+        guard manualTempBasal == false else {
+            return .loopManualTemp
+        }
         let delta = timerDate.timeIntervalSince(lastLoopDate) - Config.lag
 
         if delta <= 5.minutes.timeInterval {
@@ -71,7 +77,7 @@ struct LoopView: View {
 
     func mask(in rect: CGRect) -> Path {
         var path = Rectangle().path(in: rect)
-        if !closedLoop {
+        if !closedLoop || manualTempBasal {
             path.addPath(Rectangle().path(in: CGRect(x: rect.minX, y: rect.midY - 5, width: rect.width, height: 10)))
         }
         return path

+ 2 - 1
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -123,7 +123,8 @@ extension Home {
                 closedLoop: $state.closedLoop,
                 timerDate: $state.timerDate,
                 isLooping: $state.isLooping,
-                lastLoopDate: $state.lastLoopDate
+                lastLoopDate: $state.lastLoopDate,
+                manualTempBasal: $state.manualTempBasal
             ).onTapGesture {
                 isStatusPopupPresented = true
             }.onLongPressGesture {