Procházet zdrojové kódy

Merge branch 'tabbar-dev' into externalInsulin

polscm32 před 2 roky
rodič
revize
e9707627db

+ 0 - 1
Config.xcconfig

@@ -9,4 +9,3 @@ APP_ICON = pod_colorful
 APP_URL_SCHEME = freeaps-x
 
 #include? "ConfigOverride.xcconfig"
-//#include? "../../ConfigOverride.xcconfig"

+ 10 - 10
FreeAPS.xcodeproj/project.pbxproj

@@ -3298,7 +3298,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
 				DEVELOPMENT_ASSET_PATHS = "";
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_PREVIEWS = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
@@ -3340,7 +3340,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
 				DEVELOPMENT_ASSET_PATHS = "";
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_PREVIEWS = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(inherited)",
@@ -3385,7 +3385,7 @@
 				CODE_SIGN_ENTITLEMENTS = FreeAPSWatch/FreeAPSWatch.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				GENERATE_INFOPLIST_FILE = YES;
 				IBSC_MODULE = FreeAPSWatch_WatchKit_Extension;
 				INFOPLIST_FILE = FreeAPSWatch/Info.plist;
@@ -3420,7 +3420,7 @@
 				CODE_SIGN_ENTITLEMENTS = FreeAPSWatch/FreeAPSWatch.entitlements;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				GENERATE_INFOPLIST_FILE = YES;
 				IBSC_MODULE = FreeAPSWatch_WatchKit_Extension;
 				INFOPLIST_FILE = FreeAPSWatch/Info.plist;
@@ -3450,7 +3450,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
 				DEVELOPMENT_ASSET_PATHS = "\"FreeAPSWatch WatchKit Extension/Preview Content\"";
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = "FreeAPSWatch WatchKit Extension/Info.plist";
@@ -3490,7 +3490,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = $APP_BUILD_NUMBER;
 				DEVELOPMENT_ASSET_PATHS = "\"FreeAPSWatch WatchKit Extension/Preview Content\"";
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_PREVIEWS = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = "FreeAPSWatch WatchKit Extension/Info.plist";
@@ -3524,7 +3524,7 @@
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				INFOPLIST_FILE = FreeAPSTests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.4;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3545,7 +3545,7 @@
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CODE_SIGN_STYLE = Automatic;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				INFOPLIST_FILE = FreeAPSTests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.4;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3570,7 +3570,7 @@
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_USER_SCRIPT_SANDBOXING = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -3604,7 +3604,7 @@
 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1;
-				DEVELOPMENT_TEAM = "";
+				DEVELOPMENT_TEAM = "$(DEVELOPER_TEAM)";
 				ENABLE_USER_SCRIPT_SANDBOXING = YES;
 				GCC_C_LANGUAGE_STANDARD = gnu17;
 				GENERATE_INFOPLIST_FILE = YES;

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

@@ -33,13 +33,6 @@ extension Home {
             }
         }
 
-        func manualGlucose(hours: Int) -> [BloodGlucose] {
-            glucoseStorage.recent().filter {
-                $0.type == GlucoseType.manual.rawValue &&
-                    $0.dateString.addingTimeInterval(hours.hours.timeInterval) > Date()
-            }
-        }
-
         func pumpHistory(hours: Int) -> [PumpHistoryEvent] {
             pumpHistoryStorage.recent().filter {
                 $0.timestamp.addingTimeInterval(hours.hours.timeInterval) > Date()

+ 11 - 3
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -12,7 +12,7 @@ extension Home {
         private let timer = DispatchTimer(timeInterval: 5)
         private(set) var filteredHours = 24
         @Published var glucose: [BloodGlucose] = []
-        @Published var isManual: [BloodGlucose] = []
+        @Published var manualGlucose: [BloodGlucose] = []
         @Published var announcement: [Announcement] = []
         @Published var suggestion: Suggestion?
         @Published var uploadStats = false
@@ -234,8 +234,16 @@ extension Home {
         private func setupGlucose() {
             DispatchQueue.main.async { [weak self] in
                 guard let self = self else { return }
-                self.isManual = self.provider.manualGlucose(hours: self.filteredHours)
-                self.glucose = self.provider.filteredGlucose(hours: self.filteredHours)
+                let filteredGlucose = self.provider.filteredGlucose(hours: self.filteredHours)
+
+                for glucose in filteredGlucose {
+                    if glucose.type == GlucoseType.manual.rawValue {
+                        self.manualGlucose.append(glucose)
+                    } else {
+                        self.glucose.append(glucose)
+                    }
+                }
+
                 self.recentGlucose = self.glucose.last
                 if self.glucose.count >= 2 {
                     self.glucoseDelta = (self.recentGlucose?.glucose ?? 0) - (self.glucose[self.glucose.count - 2].glucose ?? 0)

+ 54 - 73
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -60,6 +60,7 @@ struct MainChartView: View {
     }
 
     @Binding var glucose: [BloodGlucose]
+    @Binding var manualGlucose: [BloodGlucose]
     @Binding var units: GlucoseUnits
     @Binding var eventualBG: Int?
     @Binding var suggestion: Suggestion?
@@ -332,11 +333,23 @@ extension MainChartView {
                         }
                     }
                 }
+                /// manual glucose mark
+                ForEach(manualGlucose) { item in
+                    if let manualGlucose = item.glucose {
+                        PointMark(
+                            x: .value("Time", item.dateString, unit: .second),
+                            y: .value("Value", Decimal(manualGlucose) * conversionFactor)
+                        )
+                        .symbol {
+                            Image(systemName: "drop.fill").font(.system(size: 10)).symbolRenderingMode(.monochrome)
+                                .foregroundStyle(.red)
+                        }
+                    }
+                }
             }.id("MainChart")
                 .onChange(of: glucose) { _ in
                     calculatePredictions()
                     calculateFpus()
-                    // counter()
                 }
                 .onChange(of: carbs) { _ in
                     calculateCarbs()
@@ -362,11 +375,9 @@ extension MainChartView {
                     calculatePredictions()
                 }
                 .frame(
-                    minHeight: UIScreen.main.bounds.height * 0.25
+                    minHeight: UIScreen.main.bounds.height / 3.6
                 )
-                .frame(maxHeight: UIScreen.main.bounds.height * 0.35)
                 .frame(width: fullWidth(viewWidth: screenSize.width))
-                // .chartYScale(domain: minValue ... maxValue)
                 .chartXScale(domain: startMarker ... endMarker)
                 .chartXAxis {
                     AxisMarks(values: .stride(by: .hour, count: screenHours == 24 ? 4 : 2)) { _ in
@@ -378,16 +389,6 @@ extension MainChartView {
                         AxisValueLabel(format: .dateTime.hour(.defaultDigits(amPM: .narrow)), anchor: .top)
                     }
                 }
-//                .chartYAxis {
-//                    AxisMarks { _ in
-//                        if displayYgridLines {
-//                            AxisGridLine(stroke: .init(lineWidth: 0.3, dash: [2, 3]))
-//                        } else {
-//                            AxisGridLine(stroke: .init(lineWidth: 0, dash: [2, 3]))
-//                        }
-//                        AxisValueLabel()
-//                    }
-//                }
                 .chartYAxis {
                     AxisMarks(position: .trailing) { value in
                         let upperLimit = units == .mgdL ? 400 : 22.2
@@ -444,6 +445,11 @@ extension MainChartView {
                     /// we could display scheduled temp basals with opacity etc... in the future
                     let maxEndTime = min(end, now)
 
+                    /// set mark height to 0 when insulin delivery is suspended
+                    let isInsulinSuspended = suspensions
+                        .first(where: { $0.timestamp >= temp.timestamp && $0.timestamp <= maxEndTime }) != nil
+                    let rate = (temp.rate ?? 0) * (isInsulinSuspended ? 0 : 1)
+
                     /// find next basal entry and if available set end of current entry to start of next entry
                     if let nextTemp = TempBasals.first(where: { $0.timestamp > temp.timestamp }) {
                         let nextTempStart = nextTemp.timestamp
@@ -452,29 +458,30 @@ extension MainChartView {
                             xStart: .value("start", temp.timestamp),
                             xEnd: .value("end", nextTempStart),
                             yStart: .value("rate-start", 0),
-                            yEnd: .value("rate-end", temp.rate ?? 0)
+                            yEnd: .value("rate-end", rate)
                         ).foregroundStyle(Color.insulin.opacity(0.2))
 
-                        LineMark(x: .value("Start Date", temp.timestamp), y: .value("Amount", temp.rate ?? 0))
+                        LineMark(x: .value("Start Date", temp.timestamp), y: .value("Amount", rate))
                             .lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.insulin)
 
-                        LineMark(x: .value("End Date", nextTempStart), y: .value("Amount", temp.rate ?? 0))
+                        LineMark(x: .value("End Date", nextTempStart), y: .value("Amount", rate))
                             .lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.insulin)
                     } else {
                         RectangleMark(
                             xStart: .value("start", temp.timestamp),
                             xEnd: .value("end", maxEndTime),
                             yStart: .value("rate-start", 0),
-                            yEnd: .value("rate-end", temp.rate ?? 0)
+                            yEnd: .value("rate-end", rate)
                         ).foregroundStyle(Color.insulin.opacity(0.2))
 
-                        LineMark(x: .value("Start Date", temp.timestamp), y: .value("Amount", temp.rate ?? 0))
+                        LineMark(x: .value("Start Date", temp.timestamp), y: .value("Amount", rate))
                             .lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.insulin)
 
-                        LineMark(x: .value("End Date", maxEndTime), y: .value("Amount", temp.rate ?? 0))
+                        LineMark(x: .value("End Date", maxEndTime), y: .value("Amount", rate))
                             .lineStyle(.init(lineWidth: 1)).foregroundStyle(Color.insulin)
                     }
                 }
+
                 /// dashed profile line
                 ForEach(BasalProfiles, id: \.self) { profile in
                     LineMark(
@@ -488,6 +495,31 @@ extension MainChartView {
                         series: .value("profile", "profile")
                     ).lineStyle(.init(lineWidth: 2.5, dash: [2, 4])).foregroundStyle(Color.insulin)
                 }
+
+                /// pump suspensions
+                ForEach(suspensions) { suspension in
+                    let now = Date()
+
+                    if suspension.type == EventType.pumpSuspend {
+                        let suspensionStart = suspension.timestamp
+                        let suspensionEnd = min(
+                            suspensions
+                                .first(where: { $0.timestamp > suspension.timestamp && $0.type == EventType.pumpResume })?
+                                .timestamp ?? now,
+                            now
+                        )
+                        let basalProfileDuringSuspension = BasalProfiles.first(where: { $0.startDate <= suspensionStart })
+                        let suspensionMarkHeight = basalProfileDuringSuspension?.amount ?? 1
+
+                        RectangleMark(
+                            xStart: .value("start", suspensionStart),
+                            xEnd: .value("end", suspensionEnd),
+                            yStart: .value("suspend-start", 0),
+                            yEnd: .value("suspend-end", suspensionMarkHeight)
+                        )
+                        .foregroundStyle(Color.loopGray)
+                    }
+                }
             }.onChange(of: tempBasals) { _ in
                 calculateBasals()
                 calculateTempBasals()
@@ -507,9 +539,8 @@ extension MainChartView {
                 calculateTempBasals()
             }
             .frame(
-                minHeight: UIScreen.main.bounds.height * 0.05
+                minHeight: UIScreen.main.bounds.height / 9.8
             )
-            .frame(maxHeight: UIScreen.main.bounds.height * 0.08)
             .frame(width: fullWidth(viewWidth: screenSize.width))
             .rotationEffect(.degrees(180))
             .scaleEffect(x: -1, y: 1)
@@ -857,56 +888,6 @@ extension MainChartView {
         endMarker = Date(timeIntervalSince1970: TimeInterval(NSDate().timeIntervalSince1970 + 10800))
     }
 
-    /// get y axis scale
-    /// but only call the function every 60min, i.e. every 12th glucose value
-//    private func counter() {
-//        glucoseUpdateCount += 1
-//        if glucoseUpdateCount >= maxUpdateCount {
-//            maxValue = glucose.compactMap(\.glucose).max() ?? Config.maxGlucose
-//
-//            if let maxPredValue = maxPredValue() {
-//                maxValue = max(maxValue, maxPredValue)
-//            }
-//
-//            minValue = glucose.compactMap(\.glucose).min() ?? Config.minGlucose
-//            if let minPredValue = minPredValue() {
-//                minValue = min(minValue, minPredValue)
-//            }
-//
-//            if minValue > Config.minGlucose {
-//                minValue = Config.minGlucose
-//            }
-//
-//            if maxValue < Config.maxGlucose {
-//                maxValue = Config.maxGlucose
-//            }
-//
-//            glucoseUpdateCount = 0
-//        }
-//    }
-
-//    private func maxPredValue() -> Int? {
-//        [
-//            suggestion?.predictions?.cob ?? [],
-//            suggestion?.predictions?.iob ?? [],
-//            suggestion?.predictions?.zt ?? [],
-//            suggestion?.predictions?.uam ?? []
-//        ].flatMap {
-//            $0
-//        }.max()
-//    }
-//
-//    private func minPredValue() -> Int? {
-//        [
-//            suggestion?.predictions?.cob ?? [],
-//            suggestion?.predictions?.iob ?? [],
-//            suggestion?.predictions?.zt ?? [],
-//            suggestion?.predictions?.uam ?? []
-//        ].flatMap {
-//            $0
-//        }.min()
-//    }
-
     private func calculateBasals() {
         let dayAgoTime = Date().addingTimeInterval(-1.days.timeInterval).timeIntervalSince1970
         let firstTempTime = (tempBasals.first?.timestamp ?? Date()).timeIntervalSince1970
@@ -944,4 +925,4 @@ extension MainChartView {
         }
         BasalProfiles = basals
     }
-}
+}

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

@@ -358,6 +358,7 @@ extension Home {
 
                 MainChartView(
                     glucose: $state.glucose,
+                    manualGlucose: $state.manualGlucose,
                     units: $state.units,
                     eventualBG: $state.eventualBG,
                     suggestion: $state.suggestion,